From 9e94ad159936ae0ed076a36e88a162b2dc602078 Mon Sep 17 00:00:00 2001
From: Dom Masters <dom@processcreative.com.au>
Date: Mon, 7 May 2018 07:12:31 +1000
Subject: [PATCH] Added Redux support

---
 package.json                           |  4 ++-
 public/App.jsx                         |  2 +-
 public/actions/LanguageActions.js      | 34 +++++++++++++++++++
 public/index.jsx                       | 21 ++++++++++--
 public/language/en-AU.jsx              |  4 +++
 public/nav/navbar/Navbar.jsx           | 38 +++++++++++----------
 public/page/home/Homepage.jsx          |  5 ++-
 public/reducers/LanguageReducer.js     | 47 ++++++++++++++++++++++++++
 public/reducers/RootReducer.js         | 32 ++++++++++++++++++
 public/section/Section.jsx             |  4 ++-
 public/section/video/VideoSection.jsx  | 45 ++++++++++++++++++++++++
 public/styles/components/_section.scss |  7 ++++
 public/styles/objects/_app.scss        |  1 +
 13 files changed, 219 insertions(+), 25 deletions(-)
 create mode 100644 public/actions/LanguageActions.js
 create mode 100644 public/reducers/LanguageReducer.js
 create mode 100644 public/reducers/RootReducer.js
 create mode 100644 public/section/video/VideoSection.jsx
 create mode 100644 public/styles/components/_section.scss

diff --git a/package.json b/package.json
index fdba318..5535403 100644
--- a/package.json
+++ b/package.json
@@ -27,9 +27,11 @@
     "babel-polyfill": "^6.26.0",
     "react": "^16.3.2",
     "react-dom": "^16.3.2",
+    "react-redux": "^5.0.7",
     "react-router": "^4.2.0",
     "react-router-dom": "^4.2.2",
-    "react-tap-event-plugin": "^3.0.2"
+    "react-tap-event-plugin": "^3.0.2",
+    "redux": "^4.0.0"
   },
   "devDependencies": {
     "babel-core": "^6.26.3",
diff --git a/public/App.jsx b/public/App.jsx
index 45581bd..fe1ecf1 100644
--- a/public/App.jsx
+++ b/public/App.jsx
@@ -41,7 +41,7 @@ class App extends React.Component {
           <Navbar />
           <main className="o-main">
             <Switch>
-              <Route exact path="/" component={ KitchenSinkPage } />
+              <Route exact path="/" component={ Homepage } />
             </Switch>
           </main>
         </div>
diff --git a/public/actions/LanguageActions.js b/public/actions/LanguageActions.js
new file mode 100644
index 0000000..de55b3c
--- /dev/null
+++ b/public/actions/LanguageActions.js
@@ -0,0 +1,34 @@
+// Copyright (c) 2018 Dominic Masters
+//
+// MIT License
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+import Language from './../language/Language';
+
+export const SET_LANGUAGE = "SET_LANGUAGE";
+export const LANGUAGES = Language.getLanguages();
+
+export function setLanguage(language) {
+  return {
+    type: SET_LANGUAGE,
+    code: language
+  }
+};
diff --git a/public/index.jsx b/public/index.jsx
index 9b47e9d..07d120e 100644
--- a/public/index.jsx
+++ b/public/index.jsx
@@ -25,12 +25,27 @@
 
 import React from 'react';
 import ReactDOM from 'react-dom';
+import { createStore, applyMiddleware } from 'redux';
+import { Provider } from 'react-redux';
+import RootReducer from './reducers/RootReducer'
 
-import App from './App';
-
+//Import Stylesheet
 import Styles from './styles/index';
 
+//Import Base Component
+import App from './App';
+
+//Create our redux middleware
+const store = createStore(RootReducer);
+const unsubscribe = store.subscribe(() => {
+  console.log(store.getState());
+});
+
 ReactDOM.render(
-  <App />,
+  (
+    <Provider store={store}>
+      <App />
+    </Provider>
+  ),
   document.getElementById('app')
 );
diff --git a/public/language/en-AU.jsx b/public/language/en-AU.jsx
index c989097..6dc6def 100644
--- a/public/language/en-AU.jsx
+++ b/public/language/en-AU.jsx
@@ -1,6 +1,10 @@
 import React from 'react';
 
 module.exports = {
+  "site": {
+    "name": "domsPlace"
+  },
+  
   "navbar": {
     "home": "Home",
     "about": "About",
diff --git a/public/nav/navbar/Navbar.jsx b/public/nav/navbar/Navbar.jsx
index b484fb6..457ccde 100644
--- a/public/nav/navbar/Navbar.jsx
+++ b/public/nav/navbar/Navbar.jsx
@@ -22,14 +22,18 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 import React from 'react';
+import { connect } from 'react-redux';
 import { NavLink } from 'react-router-dom'
 import Language from './../../language/Language';
 
-const NAVBAR_LINKS = {
-  "home": "/",
-  "about": "/about",
-  "contact": "/contact"
-};
+const NavbarLink = function(props) {
+  return (
+    <NavLink to={ props.to } className="o-navbar__link">
+      { Language.get("navbar." + props.title) }
+    </NavLink>
+  );
+}
+
 
 class Navbar extends React.Component {
   constructor(props) {
@@ -37,17 +41,6 @@ class Navbar extends React.Component {
   }
 
   render() {
-    let links = [];
-    let keys = Object.keys(NAVBAR_LINKS);
-    for(let i = 0; i < keys.length; i++) {
-      let k = keys[i];
-      links.push(
-        <NavLink key={k} to={NAVBAR_LINKS[k]} className="o-navbar__link">
-          { Language.get("navbar." + k) }
-        </NavLink>
-      );
-    }
-
     return (
       <section className="o-navbar__section is-stuck">
         <nav className="o-navbar">
@@ -56,14 +49,23 @@ class Navbar extends React.Component {
             <img
               src={ require('./../../images/logo.svg') }
               className="o-navbar__logo"
-              alt="domsPlace"
+              alt={ Language.get("site.name") }
             />
           </a>
-          { links }
+
+          <NavbarLink to="/" title="home" />
+          <NavbarLink to="/about" title="about" />
+          <NavbarLink to="/contact" title="contact" />
         </nav>
       </section>
     );
   }
 }
 
+const mapStateToProps = function(state) {
+  return {
+    code: state.language.code
+  }
+}
+
 export default Navbar;
diff --git a/public/page/home/Homepage.jsx b/public/page/home/Homepage.jsx
index 85b1959..1a629c6 100644
--- a/public/page/home/Homepage.jsx
+++ b/public/page/home/Homepage.jsx
@@ -23,6 +23,7 @@
 
 import React from 'react';
 import Page from './../Page';
+import VideoSection from './../../section/video/VideoSection';
 
 class Homepage extends React.Component {
   constructor(props) {
@@ -32,7 +33,9 @@ class Homepage extends React.Component {
   render() {
     return (
       <Page style="home-page">
-        Homepage
+        <VideoSection>
+          Test
+        </VideoSection>
       </Page>
     );
   }
diff --git a/public/reducers/LanguageReducer.js b/public/reducers/LanguageReducer.js
new file mode 100644
index 0000000..8c7caec
--- /dev/null
+++ b/public/reducers/LanguageReducer.js
@@ -0,0 +1,47 @@
+// Copyright (c) 2018 Dominic Masters
+//
+// MIT License
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+import Language from './../language/Language';
+import { SET_LANGUAGE, LANGUAGES } from './../actions/LanguageActions';
+
+const initialState = {
+  code: Language.getLanguage()
+};
+
+function language(state, action) {
+  if(typeof state === typeof undefined) {
+    state = initialState;
+  }
+
+  switch(action.type) {
+    case SET_LANGUAGE:
+      if(!(action.theme)) return state;
+      return {
+        code: action.code
+      };
+    default:
+      return state;
+  }
+}
+
+export default language;
diff --git a/public/reducers/RootReducer.js b/public/reducers/RootReducer.js
new file mode 100644
index 0000000..b127b9a
--- /dev/null
+++ b/public/reducers/RootReducer.js
@@ -0,0 +1,32 @@
+// Copyright (c) 2018 Dominic Masters
+//
+// MIT License
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+import { combineReducers } from 'redux';
+
+import LanguageReducer from './LanguageReducer';
+
+const rootReducer = combineReducers({
+  language: LanguageReducer
+});
+
+export default rootReducer;
diff --git a/public/section/Section.jsx b/public/section/Section.jsx
index 465ddbf..c05ad76 100644
--- a/public/section/Section.jsx
+++ b/public/section/Section.jsx
@@ -30,9 +30,11 @@ class Section extends React.Component {
 
   render() {
     return (
-      <section class="o-section">
+      <section className={"c-section" + (this.props.full?" c-section--full":"") }>
         { this.props.children }
       </section>
     );
   }
 }
+
+export default Section;
diff --git a/public/section/video/VideoSection.jsx b/public/section/video/VideoSection.jsx
new file mode 100644
index 0000000..e8ad113
--- /dev/null
+++ b/public/section/video/VideoSection.jsx
@@ -0,0 +1,45 @@
+// Copyright (c) 2018 Dominic Masters
+//
+// MIT License
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+import React from 'react';
+import Section from './../Section';
+
+class VideoSection extends React.Component {
+  constructor(props) {
+    super(props);
+  }
+
+  render() {
+    return (
+      <Section full={this.props.full}>
+        <video class="c-video-section">
+
+        </video>
+
+        { this.props.children }
+      </Section>
+    );
+  }
+}
+
+export default VideoSection;
diff --git a/public/styles/components/_section.scss b/public/styles/components/_section.scss
new file mode 100644
index 0000000..82df2fe
--- /dev/null
+++ b/public/styles/components/_section.scss
@@ -0,0 +1,7 @@
+.c-section {
+  width: 100%;
+
+  &--full {
+    height: 100%;
+  }
+}
diff --git a/public/styles/objects/_app.scss b/public/styles/objects/_app.scss
index 5a2925b..3f242eb 100644
--- a/public/styles/objects/_app.scss
+++ b/public/styles/objects/_app.scss
@@ -10,6 +10,7 @@
 .o-app {
   display: inline-block;//Fixes collapsing margins on children.
   min-height: 100vh;
+  width: 100%;
 
   //Civil Twilight
   &--style-civil-twilight {