From 8670ada517bc8beb69d152c82f282322b9ea8d64 Mon Sep 17 00:00:00 2001
From: Noah Loomans <noahloomans@gmail.com>
Date: Sun, 28 Jan 2018 15:43:11 +0100
Subject: Implement week selector in the view

---
 src/client/react/actions/view.js              |  7 +++--
 src/client/react/components/container/View.js | 18 ++++++-----
 src/client/react/components/page/User.js      |  3 +-
 src/client/react/reducers/view.js             | 43 ++++++++++++++++++---------
 4 files changed, 46 insertions(+), 25 deletions(-)

(limited to 'src/client/react')

diff --git a/src/client/react/actions/view.js b/src/client/react/actions/view.js
index f9f0be2..79ec143 100644
--- a/src/client/react/actions/view.js
+++ b/src/client/react/actions/view.js
@@ -1,17 +1,19 @@
 // eslint-disable-next-line import/prefer-default-export
-export const fetchSchedule = user => (dispatch) => {
+export const fetchSchedule = (user, week) => (dispatch) => {
   dispatch({
     type: 'VIEW/FETCH_SCHEDULE_REQUEST',
     user,
+    week,
   });
 
-  fetch(`/get/${user}`).then(
+  fetch(`/get/${user}?week=${week}`).then(
     // success
     (r) => {
       r.text().then((htmlStr) => {
         dispatch({
           type: 'VIEW/FETCH_SCHEDULE_SUCCESS',
           user,
+          week,
           htmlStr,
         });
       });
@@ -21,6 +23,7 @@ export const fetchSchedule = user => (dispatch) => {
     () => {
       dispatch({
         type: 'VIEW/FETCH_SCHEDULE_FAILURE',
+        week,
         user,
       });
     },
diff --git a/src/client/react/components/container/View.js b/src/client/react/components/container/View.js
index 9bac66f..be550cd 100644
--- a/src/client/react/components/container/View.js
+++ b/src/client/react/components/container/View.js
@@ -16,24 +16,26 @@ function cleanMeetingpointHTML(htmlStr) {
 
 class View extends React.Component {
   componentDidMount() {
-    if (!this.loadingFinished(this.props.user)) {
-      this.props.dispatch(fetchSchedule(this.props.user));
+    if (!this.loadingFinished(this.props.user, this.props.week)) {
+      this.props.dispatch(fetchSchedule(this.props.user, this.props.week));
     }
   }
 
   componentWillReceiveProps(nextProps) {
-    if (nextProps.user !== this.props.user && !this.loadingFinished(nextProps.user)) {
-      this.props.dispatch(fetchSchedule(nextProps.user));
+    if ((nextProps.user !== this.props.user || nextProps.week !== this.props.week)
+        && !this.loadingFinished(nextProps.user, nextProps.week)) {
+      this.props.dispatch(fetchSchedule(nextProps.user, nextProps.week));
     }
   }
 
-  loadingFinished(user) {
+  loadingFinished(user, week) {
     return this.props.schedules.hasOwnProperty(user) &&
-      this.props.schedules[user].state === 'finished';
+      this.props.schedules[user].hasOwnProperty(week) &&
+      this.props.schedules[user][week].state === 'finished';
   }
 
   render() {
-    if (!this.loadingFinished(this.props.user)) {
+    if (!this.loadingFinished(this.props.user, this.props.week)) {
       return (
         <div>
           Loading...
@@ -41,7 +43,7 @@ class View extends React.Component {
       );
     }
 
-    const cleanHTML = cleanMeetingpointHTML(this.props.schedules[this.props.user].htmlStr);
+    const cleanHTML = cleanMeetingpointHTML(this.props.schedules[this.props.user][this.props.week].htmlStr);
 
     return (
       // eslint-disable-next-line react/no-danger
diff --git a/src/client/react/components/page/User.js b/src/client/react/components/page/User.js
index 980070f..72e92c2 100644
--- a/src/client/react/components/page/User.js
+++ b/src/client/react/components/page/User.js
@@ -26,7 +26,8 @@ const App = ({ match, location }) => {
           <WeekSelector urlWeek={week} />
         </div>
       </div>
-      <View user={user} />
+      {/* The View object just wants the week number. */}
+      <View user={user} week={week.week()} />
     </div>
   );
 };
diff --git a/src/client/react/reducers/view.js b/src/client/react/reducers/view.js
index 276d8ae..603f1d4 100644
--- a/src/client/react/reducers/view.js
+++ b/src/client/react/reducers/view.js
@@ -1,3 +1,21 @@
+const schedule = (state = {}, action) => {
+  switch (action.type) {
+    case 'VIEW/FETCH_SCHEDULE_REQUEST':
+      return {
+        ...state,
+        state: 'fetching',
+      };
+    case 'VIEW/FETCH_SCHEDULE_SUCCESS':
+      return {
+        ...state,
+        state: 'finished',
+        htmlStr: action.htmlStr,
+      };
+    default:
+      return state;
+  }
+};
+
 const DEFAULT_STATE = {
   schedules: {},
 };
@@ -5,25 +23,22 @@ const DEFAULT_STATE = {
 const view = (state = DEFAULT_STATE, action) => {
   switch (action.type) {
     case 'VIEW/FETCH_SCHEDULE_REQUEST':
-      return {
-        ...state,
-        schedules: {
-          ...state.schedules,
-          [action.user]: {
-            state: 'fetching',
-          },
-        },
-      };
     case 'VIEW/FETCH_SCHEDULE_SUCCESS':
       return {
         ...state,
         schedules: {
           ...state.schedules,
-          [action.user]: {
-            ...state.schedules[action.user],
-            state: 'finished',
-            htmlStr: action.htmlStr,
-          },
+          [action.user]:
+            state.schedules[action.user]
+              ? {
+                // This user already exists in our state, extend it.
+                ...state.schedules[action.user],
+                [action.week]: schedule(state.schedules[action.user][action.week], action),
+              }
+              : {
+                // This user does not already exist in our state.
+                [action.week]: schedule(undefined, action),
+              },
         },
       };
     default:
-- 
cgit v1.1