Просмотр исходного кода

Add basic planner redux configuration: reducer, actions and connection to store

Tatiana Inama 7 лет назад
Родитель
Сommit
95d8df4ef8

+ 47 - 0
recipes/src/containers/Planner/actions.ts

@@ -0,0 +1,47 @@
+import { DBRecipe } from 'types/recipes';
+import { Moment } from 'moment'
+import { Meal } from 'types/planner';
+
+export const ADD_TO_BACKLOG = 'ADD_TO_BACKLOG';
+export const REMOVE_FROM_BACKLOG = 'REMOVE_FROM_BACKLOG';
+export const ASSIGN_TO_DAY = 'ASSIGN_TO_DAY';
+
+const actions = {
+  addToBacklog: (recipe: DBRecipe) => ({
+    type: ADD_TO_BACKLOG,
+    recipe,
+  }),
+  removeFromBacklog: (recipe: DBRecipe) => ({
+    type: REMOVE_FROM_BACKLOG,
+    recipe
+  }),
+  assignToDay: (recipe: DBRecipe, day: Moment, meal: Meal) => ({
+    type: ASSIGN_TO_DAY,
+    recipe,
+    day,
+    meal,
+  })
+}
+
+export type AddToBacklog = {
+  type: typeof ADD_TO_BACKLOG,
+  recipe: DBRecipe,
+};
+
+export type RemoveFromBacklog = {
+  type: typeof REMOVE_FROM_BACKLOG,
+  recipe: DBRecipe
+}
+
+export type AssignToDay = {
+  type: typeof ASSIGN_TO_DAY,
+  recipe: DBRecipe,
+  day: Moment,
+  meal: Meal
+}
+
+export type ActionTypes = AddToBacklog | RemoveFromBacklog | AssignToDay;
+
+export default {
+  ...actions
+}

+ 38 - 0
recipes/src/containers/Planner/index.tsx

@@ -0,0 +1,38 @@
+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 } from 'types/planner';
+import { Grid, Row, Cell } from "@material/react-layout-grid";
+
+interface PlannerContainerProps extends RouteComponentProps, PlannerState {
+}
+
+class PlannerContainer extends Component<PlannerContainerProps> {
+  render () {
+    return (
+      <div className='cbk-planner'>
+        <Navbar
+          title='Planner'
+        >
+          <div>Week {this.props.data.week}</div>
+        </Navbar>
+        <section className='cbk-planner__body'>
+          <div className='cbk-planner__body__calendar'>
+            
+          </div>
+          <div className='cbk-planner__body__backlog'></div>
+        </section>
+      </div>
+    );
+  }
+}
+
+const mapStateToProps = (state: AppState) => {
+  return state.planner
+}
+
+export default connect(
+  mapStateToProps
+)(PlannerContainer);

+ 51 - 0
recipes/src/containers/Planner/reducers.ts

@@ -0,0 +1,51 @@
+import { ActionTypes, ADD_TO_BACKLOG, ASSIGN_TO_DAY } from './actions';
+import Planner, { PlannerState } from 'types/planner';
+import { getWeekNumber, mkWeekDay, getWeekDay } from 'services/time';
+
+const initialState: PlannerState = {
+  isFetching: false,
+  data: {
+    from: mkWeekDay(1),
+    to: mkWeekDay(7),
+    week: getWeekNumber(),
+    monday:   { date: mkWeekDay(1)},
+    tuesday:  { date: mkWeekDay(2)},
+    wednsday: { date: mkWeekDay(3)},
+    thursday: { date: mkWeekDay(4)},
+    friday:   { date: mkWeekDay(5)},
+    saturday: { date: mkWeekDay(6)},
+    sunday:   { date: mkWeekDay(7)},
+  },
+  backlog: []
+}
+
+const PlannerReducer = (
+  state = initialState,
+  action: ActionTypes
+): PlannerState => {
+  switch (action.type) {
+    case 'ADD_TO_BACKLOG': 
+      return {
+        ...state,
+        backlog: state.backlog.concat([action.recipe])
+      };
+    case 'ASSIGN_TO_DAY':
+      return {
+        ...state,
+        [getWeekDay(action.day)]: {
+          date: action.day,
+          [action.meal]: action.recipe
+        }
+      };
+    case 'REMOVE_FROM_BACKLOG':
+      return {
+        ...state,
+        backlog: state.backlog.filter(recipe => recipe._id !== action.recipe._id)
+      }
+    default:
+      return state
+  }
+}
+
+export default PlannerReducer;
+

+ 2 - 1
recipes/src/route.config.tsx

@@ -5,6 +5,7 @@ import CreateRecipe from 'containers/Recipes/Create';
 import ViewRecipe from 'containers/Recipes/View';
 import ViewRecipe from 'containers/Recipes/View';
 import EditRecipe from 'containers/Recipes/Edit';
 import EditRecipe from 'containers/Recipes/Edit';
 import ShoppingList from 'containers/ShoppingCart/List';
 import ShoppingList from 'containers/ShoppingCart/List';
+import PlannerContainer from 'containers/Planner';
 
 
 const emptyRoute = (title: string) => (props: any) => {
 const emptyRoute = (title: string) => (props: any) => {
   return (<h1>{title} {props.match.params && props.match.params.id}</h1>);
   return (<h1>{title} {props.match.params && props.match.params.id}</h1>);
@@ -27,7 +28,7 @@ const routes = [
     }]
     }]
   }, {
   }, {
     path: '/planner',
     path: '/planner',
-    component: emptyRoute('planner'),
+    component: PlannerContainer,
     routes: [{
     routes: [{
       path: '/planner/lala',
       path: '/planner/lala',
       component: emptyRoute('planner lala'),
       component: emptyRoute('planner lala'),

+ 13 - 0
recipes/src/services/time.ts

@@ -0,0 +1,13 @@
+import moment, { Moment } from 'moment';
+
+export const mkWeekDay = (day: string | number): Moment => moment().isoWeekday(day);
+
+export const getWeekNumber = (): number => moment().isoWeek();
+
+export const getWeekDay = (day: Moment): string => day.format('dddd').toLowerCase();
+
+export default {
+  mkWeekDay,
+  getWeekNumber,
+  getWeekDay
+}

+ 2 - 0
recipes/src/store/configureStore.ts

@@ -3,11 +3,13 @@ import thunk from 'redux-thunk';
 import { composeWithDevTools } from 'redux-devtools-extension';
 import { composeWithDevTools } from 'redux-devtools-extension';
 import { recipesReducer } from 'containers/Recipes/List/reducers';
 import { recipesReducer } from 'containers/Recipes/List/reducers';
 import shoppingCartReducer from 'containers/ShoppingCart/reducers';
 import shoppingCartReducer from 'containers/ShoppingCart/reducers';
+import plannerReducer from 'containers/Planner/reducers';
 
 
 const composeEnhancers = composeWithDevTools({});
 const composeEnhancers = composeWithDevTools({});
 const rootReducer = combineReducers({
 const rootReducer = combineReducers({
   recipes: recipesReducer,
   recipes: recipesReducer,
   shoppingCart: shoppingCartReducer,
   shoppingCart: shoppingCartReducer,
+  planner: plannerReducer
 })
 })
 
 
 const configureStore = () => {
 const configureStore = () => {

+ 36 - 0
recipes/src/types/planner.ts

@@ -0,0 +1,36 @@
+import { Moment } from "moment";
+import { DBRecipe } from "./recipes";
+
+export type Weekday =
+  'monday' |
+  'tuesday' |
+  'wednsday' |
+  'thursday' |
+  'friday' |
+  'saturday' |
+  'sunday';
+
+export type DayPlan = {
+  date: Moment,
+  lunch?: DBRecipe,
+  dinner?: DBRecipe,
+};
+
+export type WeekPlan = {
+  [day in Weekday]: DayPlan;
+};
+
+export type Meal = 'lunch' | 'dinner';
+
+export default interface Planner extends WeekPlan {
+  week: number,
+  from: Moment,
+  to: Moment
+};
+
+export interface PlannerState {
+  isFetching: boolean,
+  error?: string,
+  data: Planner,
+  backlog: DBRecipe[]
+}