From 1121303e0c31a986f1e75316ddeab04ea4f2f751 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Gonz=C3=A1lez=20Mu=C3=B1oz?= Date: Sat, 23 Feb 2019 21:22:06 +0100 Subject: [PATCH] Migrates terms of service and how to pages --- .../app/how-to/component.js | 40 ++------- layout/app/how-to/index.js | 9 ++ .../app/terms-of-service/component.js | 52 +++-------- layout/app/terms-of-service/index.js | 8 ++ modules/index.js | 2 + modules/static-pages/actions.js | 32 +++++++ modules/static-pages/index.js | 5 ++ modules/static-pages/initial-state.js | 14 +++ modules/static-pages/reducers.js | 23 +++++ pages/app/Dashboards.js | 88 ------------------- pages/app/about/component.js | 4 +- .../app/attribution-requirements/component.js | 4 +- pages/app/how-to/component.js | 24 +++++ pages/app/how-to/index.js | 3 + pages/app/policy/component.js | 5 +- pages/app/terms-of-service/component.js | 24 +++++ pages/app/terms-of-service/index.js | 3 + pages/app/topics/index.js | 4 +- redactions/index.js | 1 - redactions/static_pages.js | 86 ------------------ routes.js | 4 +- services/static-page.js | 21 +++++ 22 files changed, 200 insertions(+), 256 deletions(-) rename pages/app/Howto.js => layout/app/how-to/component.js (60%) create mode 100644 layout/app/how-to/index.js rename pages/app/Terms.js => layout/app/terms-of-service/component.js (53%) create mode 100644 layout/app/terms-of-service/index.js create mode 100644 modules/static-pages/actions.js create mode 100644 modules/static-pages/index.js create mode 100644 modules/static-pages/initial-state.js create mode 100644 modules/static-pages/reducers.js delete mode 100644 pages/app/Dashboards.js create mode 100644 pages/app/how-to/component.js create mode 100644 pages/app/how-to/index.js create mode 100644 pages/app/terms-of-service/component.js create mode 100644 pages/app/terms-of-service/index.js delete mode 100644 redactions/static_pages.js create mode 100644 services/static-page.js diff --git a/pages/app/Howto.js b/layout/app/how-to/component.js similarity index 60% rename from pages/app/Howto.js rename to layout/app/how-to/component.js index 01c77627b..9c6107df2 100644 --- a/pages/app/Howto.js +++ b/layout/app/how-to/component.js @@ -1,33 +1,24 @@ -import React, { PureComponent } from 'react'; +import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import renderHTML from 'react-render-html'; -import { connect } from 'react-redux'; -import { getStaticData } from 'redactions/static_pages'; + +// components import Layout from 'layout/layout/layout-app'; -class Howto extends PureComponent { - static async getInitialProps({ store }) { - // Get static data - await store.dispatch(getStaticData('how-to')); - return {}; - } +class LayoutHowTo extends PureComponent { + static propTypes = { data: PropTypes.object.isRequired } render() { const { data } = this.props; - const styles = {}; + const styles = { ...(data && data.photo) && { backgroundImage: `url(${process.env.STATIC_SERVER_URL}${data.photo.cover})` } }; if (!data) return null; - if (data && data.photo) { - styles.backgroundImage = `url(${process.env.STATIC_SERVER_URL}${data.photo.cover})`; - } - return (
@@ -50,7 +41,7 @@ class Howto extends PureComponent {
- {renderHTML(data.content || '')} + {renderHTML(data.content)}
@@ -64,17 +55,4 @@ class Howto extends PureComponent { } } -Howto.propTypes = { - data: PropTypes.object, - getStaticData: PropTypes.func -}; - -const mapStateToProps = state => ({ - data: state.staticPages['how-to'] -}); - -const mapDispatchToProps = { - getStaticData -}; - -export default connect(mapStateToProps, mapDispatchToProps)(Howto); +export default LayoutHowTo; diff --git a/layout/app/how-to/index.js b/layout/app/how-to/index.js new file mode 100644 index 000000000..330bfdb14 --- /dev/null +++ b/layout/app/how-to/index.js @@ -0,0 +1,9 @@ +import { connect } from 'react-redux'; + +// component +import LayoutHowTo from './component'; + +export default connect( + state => ({ data: state.staticPages['how-to'] }), + null +)(LayoutHowTo); diff --git a/pages/app/Terms.js b/layout/app/terms-of-service/component.js similarity index 53% rename from pages/app/Terms.js rename to layout/app/terms-of-service/component.js index 5a61dbae8..5f9be09fd 100644 --- a/pages/app/Terms.js +++ b/layout/app/terms-of-service/component.js @@ -1,44 +1,32 @@ -import React from 'react'; +import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import renderHTML from 'react-render-html'; -import withRedux from 'next-redux-wrapper'; -import { initStore } from 'store'; -import { getStaticData } from 'redactions/static_pages'; - -import Page from 'layout/page'; +// components import Layout from 'layout/layout/layout-app'; -class Terms extends Page { - static async getInitialProps(context) { - const props = await super.getInitialProps(context); - - // Get static data - await context.store.dispatch(getStaticData('terms-of-service')); - return { ...props }; - } +class LayoutTermsOfService extends PureComponent { + static propTypes = { data: PropTypes.object.isRequired } render() { const { data } = this.props; - const styles = {}; + const styles = { ...(data && data.photo) && { backgroundImage: `url(${process.env.STATIC_SERVER_URL}${data.photo.cover})` } }; if (!data) return null; - if (data && data.photo) { - styles.backgroundImage = `url(${process.env.STATIC_SERVER_URL}${data.photo.cover})`; - } - return (
-
+
@@ -56,13 +44,12 @@ class Terms extends Page {
- {renderHTML(data.content || '')} + {renderHTML(data.content)}
-
- } +
}
@@ -70,17 +57,4 @@ class Terms extends Page { } } -Terms.propTypes = { - data: PropTypes.object, - getStaticData: PropTypes.func -}; - -const mapStateToProps = state => ({ - data: state.staticPages['terms-of-service'] -}); - -const mapDispatchToProps = { - getStaticData -}; - -export default withRedux(initStore, mapStateToProps, mapDispatchToProps)(Terms); +export default LayoutTermsOfService; diff --git a/layout/app/terms-of-service/index.js b/layout/app/terms-of-service/index.js new file mode 100644 index 000000000..a02c202d5 --- /dev/null +++ b/layout/app/terms-of-service/index.js @@ -0,0 +1,8 @@ +import { connect } from 'react-redux'; + +import LayoutTermsOfService from './component'; + +export default connect( + state => ({ data: state.staticPages['terms-of-service'] }), + null +)(LayoutTermsOfService); diff --git a/modules/index.js b/modules/index.js index ea8b8f866..e58be5d7d 100644 --- a/modules/index.js +++ b/modules/index.js @@ -1,10 +1,12 @@ import { handleModule } from 'redux-tools'; import dashboardsModule from './dashboards'; +import staticPagesModules from './static-pages'; import topicsModule from './topics'; export default { dashboards: handleModule(dashboardsModule), + staticPages: handleModule(staticPagesModules), topics: handleModule(topicsModule) }; diff --git a/modules/static-pages/actions.js b/modules/static-pages/actions.js new file mode 100644 index 000000000..6edc35dfc --- /dev/null +++ b/modules/static-pages/actions.js @@ -0,0 +1,32 @@ +import { createAction, createThunkAction } from 'redux-tools'; + +// service +import { fetchStaticPage } from 'services/static-page'; + +// actions +export const setContentPage = createAction('STATIC-PAGES__SET-CONTENT-PAGE'); +export const setLoading = createAction('STATIC-PAGES__SET-LOADING'); +export const setError = createAction('STATIC-PAGES__SET-ERROR'); + +export const getStaticPage = createThunkAction('STATIC-PAGES__GET-STATIC-PAGE', + page => (dispatch) => { + dispatch(setLoading({ key: page, value: true })); + dispatch(setError(true)); + + return fetchStaticPage(page) + .then((contentPage) => { + dispatch(setContentPage({ key: page, value: contentPage })); + dispatch(setLoading(false)); + }) + .catch((err) => { + dispatch(setError(err)); + dispatch(setLoading(false)); + }); + }); + +export default { + setContentPage, + setLoading, + setError, + getStaticPage +}; diff --git a/modules/static-pages/index.js b/modules/static-pages/index.js new file mode 100644 index 000000000..518de0108 --- /dev/null +++ b/modules/static-pages/index.js @@ -0,0 +1,5 @@ +import * as actions from './actions'; +import * as reducers from './reducers'; +import initialState from './initial-state'; + +export default { actions, reducers, initialState }; diff --git a/modules/static-pages/initial-state.js b/modules/static-pages/initial-state.js new file mode 100644 index 000000000..06a7a4dfe --- /dev/null +++ b/modules/static-pages/initial-state.js @@ -0,0 +1,14 @@ +export default { + loading: true, + error: null, + about: {}, + apps: {}, + 'contribute-data': {}, + 'develop-app': {}, + getInvolved: {}, + 'how-to': {}, + 'join-community': {}, + 'submit-an-insight': {}, + 'terms-of-service': {}, + topics: {} +}; diff --git a/modules/static-pages/reducers.js b/modules/static-pages/reducers.js new file mode 100644 index 000000000..787dbde10 --- /dev/null +++ b/modules/static-pages/reducers.js @@ -0,0 +1,23 @@ +import * as actions from './actions'; + +export default { + [actions.setContentPage]: (state, { payload }) => + ({ + ...state, + [payload.key]: { + ...state[payload.key], + ...payload.value + } + }), + + [actions.setLoading]: (state, { payload }) => + ({ + ...state, + loading: payload + }), + [actions.setError]: (state, { payload }) => + ({ + ...state, + error: payload + }) +}; diff --git a/pages/app/Dashboards.js b/pages/app/Dashboards.js deleted file mode 100644 index ec40a0e93..000000000 --- a/pages/app/Dashboards.js +++ /dev/null @@ -1,88 +0,0 @@ -import React from 'react'; -import { Router } from 'routes'; - -// Redux -import withRedux from 'next-redux-wrapper'; -import { initStore } from 'store'; -import { fetchDashboards, setPagination, setExpanded, setAdd, setSelected } from 'components/dashboards/thumbnail-list/dashboard-thumbnail-list-actions'; - -// Components -import Page from 'layout/page'; -import Layout from 'layout/layout/layout-app'; -import DashboardThumbnailList from 'components/dashboards/thumbnail-list/dashboard-thumbnail-list'; - -class Dashboards extends Page { - static async getInitialProps(context) { - const props = await super.getInitialProps(context); - - // Dashboard thumbnail list - context.store.dispatch(setPagination(false)); - context.store.dispatch(setAdd(false)); - context.store.dispatch(setSelected(null)); - - await context.store.dispatch(fetchDashboards({ 'filter[published]': 'true' })); - - return { ...props }; - } - - - render() { - const { url, user } = this.props; - - return ( - -
-
-
-
-
-

Dashboards

-
-
-
-
-
- -
-
-
-
- { - // We need to make an amendment in the Wysiwyg to have this working - Router.pushRoute('dashboards_detail', { slug }) - .then(() => { - window.scrollTo(0, 0); - }); - }} - onExpand={(bool) => { - this.props.setExpanded(bool); - }} - /> -
-
-
-
-
- ); - } -} - -const mapStateToProps = null; - -const mapDispatchToProps = { - fetchDashboards, - setExpanded, - setPagination, - setAdd, - setSelected -}; - -export default withRedux(initStore, mapStateToProps, mapDispatchToProps)(Dashboards); diff --git a/pages/app/about/component.js b/pages/app/about/component.js index eef84eda4..92190eed5 100644 --- a/pages/app/about/component.js +++ b/pages/app/about/component.js @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; // actions -import { getStaticData } from 'redactions/static_pages'; +import { getStaticPage } from 'modules/static-pages/actions'; // components import AboutLayout from 'layout/app/about'; @@ -9,7 +9,7 @@ import AboutLayout from 'layout/app/about'; class AboutPage extends PureComponent { static async getInitialProps({ store }) { // fetchs static data for about page - await store.dispatch(getStaticData('about')); + await store.dispatch(getStaticPage('about')); return {}; } diff --git a/pages/app/attribution-requirements/component.js b/pages/app/attribution-requirements/component.js index fb32d5909..0c36bc8c4 100644 --- a/pages/app/attribution-requirements/component.js +++ b/pages/app/attribution-requirements/component.js @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; // actions -import { getStaticData } from 'redactions/static_pages'; +import { getStaticPage } from 'modules/static-pages/actions'; // components import LayoutAttributionRequirements from 'layout/app/attribution-requirements'; @@ -9,7 +9,7 @@ import LayoutAttributionRequirements from 'layout/app/attribution-requirements'; class AttributionRequirementsPage extends PureComponent { static async getInitialProps({ store }) { // fetchs static data for attribution & requirements page - await store.dispatch(getStaticData('api-attribution-requirements')); + await store.dispatch(getStaticPage('api-attribution-requirements')); return {}; } diff --git a/pages/app/how-to/component.js b/pages/app/how-to/component.js new file mode 100644 index 000000000..305d32a93 --- /dev/null +++ b/pages/app/how-to/component.js @@ -0,0 +1,24 @@ +import React, { PureComponent } from 'react'; + +// actions +import { getStaticPage } from 'modules/static-pages/actions'; + +// component +import LayoutHowTo from 'layout/app/how-to'; + +class HowtoPage extends PureComponent { + static async getInitialProps({ store }) { + const { getState, dispatch } = store; + const { staticPages } = getState(); + + if (!Object.keys(staticPages['how-to']).length) await dispatch(getStaticPage('how-to')); + + return {}; + } + + render() { + return (); + } +} + +export default HowtoPage; diff --git a/pages/app/how-to/index.js b/pages/app/how-to/index.js new file mode 100644 index 000000000..6aa86e8b0 --- /dev/null +++ b/pages/app/how-to/index.js @@ -0,0 +1,3 @@ +import HowToPage from './component'; + +export default HowToPage; diff --git a/pages/app/policy/component.js b/pages/app/policy/component.js index bf7e2ed75..cc14622bf 100644 --- a/pages/app/policy/component.js +++ b/pages/app/policy/component.js @@ -1,15 +1,14 @@ import React, { PureComponent } from 'react'; // actions -import { getStaticData } from 'redactions/static_pages'; +import { getStaticPage } from 'modules/static-pages/actions'; // components import LayoutPolicy from 'layout/app/policy'; class PolicyPage extends PureComponent { static async getInitialProps({ store }) { - // fetchs static data for policy page - await store.dispatch(getStaticData('privacy-policy')); + await store.dispatch(getStaticPage('privacy-policy')); return {}; } diff --git a/pages/app/terms-of-service/component.js b/pages/app/terms-of-service/component.js new file mode 100644 index 000000000..d6af913af --- /dev/null +++ b/pages/app/terms-of-service/component.js @@ -0,0 +1,24 @@ +import React, { PureComponent } from 'react'; + +// actions +import { getStaticPage } from 'modules/static-pages/actions'; + +// components +import LayoutTermsOfService from 'layout/app/terms-of-service'; + +class TermsOfServicePage extends PureComponent { + static async getInitialProps({ store }) { + const { getState, dispatch } = store; + const { staticPages } = getState(); + + if (!Object.keys(staticPages['terms-of-service']).length) await dispatch(getStaticPage('terms-of-service')); + + return {}; + } + + render() { + return (); + } +} + +export default TermsOfServicePage; diff --git a/pages/app/terms-of-service/index.js b/pages/app/terms-of-service/index.js new file mode 100644 index 000000000..b8f25e1d9 --- /dev/null +++ b/pages/app/terms-of-service/index.js @@ -0,0 +1,3 @@ +import TermsOfService from './component'; + +export default TermsOfService; diff --git a/pages/app/topics/index.js b/pages/app/topics/index.js index ce40bbbc3..254cd426b 100644 --- a/pages/app/topics/index.js +++ b/pages/app/topics/index.js @@ -7,7 +7,7 @@ import Page from 'layout/page'; import withRedux from 'next-redux-wrapper'; import { initStore } from 'store'; -import { getStaticData } from 'redactions/static_pages'; +import { getStaticPage } from 'modules/static-pages/actions'; import Topics from 'layout/topics'; @@ -15,7 +15,7 @@ class TopicsPage extends Page { static async getInitialProps(context) { const props = await super.getInitialProps(context); - await context.store.dispatch(getStaticData('topics')); + await context.store.dispatch(getStaticPage('topics')); return props; } diff --git a/redactions/index.js b/redactions/index.js index a6a33da60..f3113346b 100644 --- a/redactions/index.js +++ b/redactions/index.js @@ -3,7 +3,6 @@ export { default as widget } from './widget'; export { default as common } from './common'; export { default as partnerDetail } from './partnerDetail'; export { default as tooltip } from './tooltip'; -export { default as staticPages } from './static_pages'; export { default as modal } from './modal'; export { default as user } from './user'; export { default as routes } from './routes'; diff --git a/redactions/static_pages.js b/redactions/static_pages.js deleted file mode 100644 index 55ca7744b..000000000 --- a/redactions/static_pages.js +++ /dev/null @@ -1,86 +0,0 @@ -/* global config */ -import 'isomorphic-fetch'; - -/** - * CONSTANTS -*/ -const GET_STATIC_SUCCESS = 'static_pages/GET_STATIC_SUCCESS'; -const GET_STATIC_ERROR = 'static_pages/GET_STATIC_ERROR'; -const GET_STATIC_LOADING = 'static_pages/GET_STATIC_LOADING'; - -/** - * REDUCER -*/ -const initialState = { - loading: false, - error: false, - about: {}, - getInvolved: {}, - apps: {}, - 'submit-an-insight': {}, - 'join-community': {}, - 'develop-app': {}, - 'contribute-data': {}, - topics: {} -}; - -export default function (state = initialState, action) { - switch (action.type) { - case GET_STATIC_SUCCESS: { - const staticData = {}; - staticData[action.payload.name] = action.payload.data; - return Object.assign({}, state, - { - loading: false, - error: false - }, - staticData); - } - - case GET_STATIC_ERROR: { - return Object.assign({}, state, { - loading: false, - error: true - }); - } - - case GET_STATIC_LOADING: { - return Object.assign({}, state, { - loading: true, - error: false - }); - } - - default: - return state; - } -} - -/** - * ACTIONS - * - getStaticData -*/ -export function getStaticData(slug) { - return (dispatch) => { - // Waiting for fetch from server -> Dispatch loading - dispatch({ type: GET_STATIC_LOADING }); - return fetch(new Request(`${process.env.WRI_API_URL}/static_page/${slug}`)) - .then((response) => { - if (response.ok) return response.json(); - throw new Error(response.statusText); - }) - .then((response) => { - dispatch({ - type: GET_STATIC_SUCCESS, - payload: { name: slug, data: response.data.attributes } - }); - }) - .catch((err) => { - // Fetch from server ko -> Dispatch error - dispatch({ - type: GET_STATIC_ERROR, - payload: err.message - }); - }); - }; -} diff --git a/routes.js b/routes.js index ca3c6d743..8adf69a20 100644 --- a/routes.js +++ b/routes.js @@ -37,7 +37,7 @@ routes.add('about', '/about', 'app/about'); routes.add('about_partners', '/about/partners', 'app/partners'); routes.add('about_faqs', '/about/faqs', 'app/Faqs'); routes.add('about_contact-us', '/about/contact-us', 'app/contact-us'); -routes.add('about_howto', '/about/howto', 'app/Howto'); +routes.add('about_howto', '/about/howto', 'app/how-to'); routes.add('partner', '/about/partners/:id', 'app/PartnerDetail'); routes.add('newsletter', '/about/newsletter', 'app/newsletter'); @@ -72,7 +72,7 @@ routes.add('myrw', '/myrw/:tab?/:subtab?', 'app/MyRW'); routes.add('myrw_detail', '/myrw-detail/:tab?/:id?/:subtab?', 'app/MyRWDetail'); // ------ TERMS && POLICY ------------- -routes.add('terms-of-service', '/terms-of-service', 'app/Terms'); +routes.add('terms-of-service', '/terms-of-service', 'app/terms-of-service'); routes.add('privacy-policy', '/privacy-policy', 'app/policy'); routes.add('attribution-requirements', '/api-attribution-requirements', 'app/attribution-requirements'); diff --git a/services/static-page.js b/services/static-page.js new file mode 100644 index 000000000..a61d17636 --- /dev/null +++ b/services/static-page.js @@ -0,0 +1,21 @@ +import { WRIAPI } from 'utils/axios'; +import WRISerializer from 'wri-json-api-serializer'; + +// API docs: TBD + +/** + * Fetchs content of a specific page. + * + * @param {String} id - id of the page to fetch. + * @returns {Object[]} page content serialized. + */ + +export const fetchStaticPage = id => + WRIAPI.get(`/static_page/${id}`) + .then((response) => { + const { status, statusText, data } = response; + if (status >= 400) throw new Error(statusText); + return WRISerializer(data); + }); + +export default { fetchStaticPage };