diff --git a/package.json b/package.json index f81a9c4..c05befe 100644 --- a/package.json +++ b/package.json @@ -8,17 +8,21 @@ "@babel/preset-react": "^7.0.0", "@material-ui/core": "^4.2.1", "@material-ui/icons": "^4.2.1", + "axios": "^0.19.0", "react": "^16.8.6", "react-dom": "^16.8.6", "react-loader-spinner": "^2.3.0", "react-redux": "^7.1.0", + "react-redux-loading": "^1.0.1", "react-router": "^5.0.1", "react-router-dom": "^5.0.1", "react-scripts": "3.0.1", "redux": "^4.0.4", "redux-logger": "^3.0.6", "redux-mock-store": "^1.5.3", - "redux-thunk": "^2.3.0" + "redux-thunk": "^2.3.0", + "slugify": "^1.3.4", + "titlecase": "^1.1.3" }, "scripts": { "start": "react-scripts start", diff --git a/src/App.css b/src/App.css deleted file mode 100644 index cf280ea..0000000 --- a/src/App.css +++ /dev/null @@ -1,33 +0,0 @@ -.App { - text-align: center; -} - -.App-logo { - animation: App-logo-spin infinite 20s linear; - height: 40vmin; - pointer-events: none; -} - -.App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; -} - -.App-link { - color: #61dafb; -} - -@keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/src/actions/actions.types.js b/src/actions/actions.types.js new file mode 100644 index 0000000..06e205b --- /dev/null +++ b/src/actions/actions.types.js @@ -0,0 +1,3 @@ +export const SET_AUTH_USER = 'SET_AUTH_USER'; + +export const GET_DRB_BOOKS = 'GET_DRB_BOOKS'; diff --git a/src/actions/authUser.js b/src/actions/authUser.js index e1e018c..0ead889 100644 --- a/src/actions/authUser.js +++ b/src/actions/authUser.js @@ -1,13 +1,10 @@ -import { SET_AUTH_USER } from './constants'; +// /* eslint-disable no-unused-vars */ +// import { SET_AUTH_USER } from './actions.types'; -// action creator -export const set_auth_action_creator = id => ({ type: SET_AUTH_USER, id }); +// // action creator +// export const set_auth_action_creator = id => ({ type: SET_AUTH_USER, id }); -// action dispatcher -export const set_auth_user = () => { - return dispatch => { - return new Promise.resolve('AUTH_USER_ID').then(user => { - dispatch(set_auth_action_creator(user)); - }); - }; -}; +// // action dispatcher +// export const set_auth_user = () => dispatch => { +// return dispatch; +// }; diff --git a/src/actions/constants.js b/src/actions/constants.js deleted file mode 100644 index 0b293e8..0000000 --- a/src/actions/constants.js +++ /dev/null @@ -1 +0,0 @@ -export const SET_AUTH_USER = ''; diff --git a/src/actions/drbActions.js b/src/actions/drbActions.js new file mode 100644 index 0000000..62aaac0 --- /dev/null +++ b/src/actions/drbActions.js @@ -0,0 +1,12 @@ +import { GET_DRB_BOOKS } from './actions.types'; + +const get_drb_books_action_creator = booklist => { + return { + type: GET_DRB_BOOKS, + booklist, + }; +}; + +export const get_drb_books = (book_list) => dispatch => { + dispatch(get_drb_books_action_creator(book_list)); +}; diff --git a/src/components/AppRoutes.js b/src/components/AppRoutes.js index 9c438bd..4bd0ed6 100644 --- a/src/components/AppRoutes.js +++ b/src/components/AppRoutes.js @@ -4,16 +4,16 @@ import PageLoader from './PageLoader'; import PublicRoute from '../routes/PublicRoute'; import Error404 from './Error404'; -const env = process.env.NODE_ENV; -const path = env === 'development' ? '/' : '/Ethodoxy/'; - const Home = lazy(() => import('./Home')); +const DouayBooks = lazy(() => import('./Douay.books')); const Routes = () => ( - + // eslint-disable-next-line no-undef + }> - + + {/* catch all invalid urls */} diff --git a/src/components/Douay.books.js b/src/components/Douay.books.js new file mode 100644 index 0000000..275e81b --- /dev/null +++ b/src/components/Douay.books.js @@ -0,0 +1,98 @@ +import React, { Fragment, useState, useEffect } from 'react'; +import axios from 'axios'; +import titlecase from 'titlecase'; +import slugify from 'slugify'; + +import Grid from '@material-ui/core/Grid'; +import { makeStyles } from '@material-ui/core/styles'; +import { useDispatch } from 'react-redux'; + +import { DR_BOOKS_URL, default_headers } from '../constants'; +import LinkGridItem from './LinkGridItem'; + +import { get_drb_books } from '../actions/drbActions'; + +const useStyles = makeStyles({ + container: { + paddingTop: '20px' + }, +}); + +const DouayBooks = () => { + const classes = useStyles(); + const dispatch = useDispatch(); + const [books, setBooks] = useState(['a']); + + useEffect(() => { + const getBooks = async () => { + let books = []; + let url = DR_BOOKS_URL; + const config = { headers: { ...default_headers }}; + + while (url) { + const { data } = await axios.get(url, config); + const { results, next } = data; + books = books.concat(results); + url = next; + } + setBooks(books); + dispatch(get_drb_books(books)); + }; + getBooks(); + }, [dispatch]); + + + return ( + +

Douay-Rheims Bible

+ +

Old Testament

+ + { + books + .filter(book => book.testament==='old testament') + .map(book => { + return ( + + ); + }) + } + + +

New Testament

+ + { + books + .filter(book => book.testament==='new testament') + .map(book => { + return ( + + ); + }) + } + +
+ ); +}; + +export default DouayBooks; diff --git a/src/components/ErrorBoundary.js b/src/components/ErrorBoundary.js index d2da1f4..fb27b97 100644 --- a/src/components/ErrorBoundary.js +++ b/src/components/ErrorBoundary.js @@ -11,6 +11,7 @@ class ErrorBoundary extends Component { componentDidCatch(error, info) { // You can also log the error to an error reporting service + // eslint-disable-next-line no-console console.log({ error, info }); } @@ -27,7 +28,9 @@ class ErrorBoundary extends Component { } ErrorBoundary.propTypes = { - children: propTypes.object.isRequired + children: propTypes.oneOfType([ + propTypes.array, propTypes.object + ]).isRequired, }; export default ErrorBoundary; diff --git a/src/components/Footer.js b/src/components/Footer.js index b99862f..98f6e1a 100644 --- a/src/components/Footer.js +++ b/src/components/Footer.js @@ -4,7 +4,7 @@ const Footer = () => { return (

- Built with material UI and React + Built with React and material UI (orjichidi95@gmail.com)

); diff --git a/src/components/Home.js b/src/components/Home.js index 211a8f6..283981d 100644 --- a/src/components/Home.js +++ b/src/components/Home.js @@ -1,11 +1,38 @@ -import React from 'react'; +import React, { Fragment } from 'react'; import PropTypes from 'prop-types'; +import Grid from '@material-ui/core/Grid'; +import { makeStyles } from '@material-ui/core/styles'; import { connect } from 'react-redux'; -const Home = props => { - return
Welcome {props.auth}
; +import LinkGridItem from './LinkGridItem'; + +const useStyles = makeStyles({ + container: { + paddingTop: '20px' + }, +}); + +const Home = () => { + const classes = useStyles(); + + return ( + +

Available titles

+ + + + +
+ ); }; + Home.propTypes = { auth: PropTypes.string }; diff --git a/src/components/LinkGridItem.js b/src/components/LinkGridItem.js new file mode 100644 index 0000000..9a290ed --- /dev/null +++ b/src/components/LinkGridItem.js @@ -0,0 +1,36 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Link } from 'react-router-dom'; +import Grid from '@material-ui/core/Grid'; +import { makeStyles } from '@material-ui/core/styles'; + +const useStyles = makeStyles({ + item: { + // padding: '0px', + // margin: '5px', + } +}); + +const LinkGridItem = props => { + const classes = useStyles(); + const { title, location } = props; + + return ( + + { title } + + ); +}; + + +LinkGridItem.propTypes = { + location: PropTypes.string.isRequired, + title: PropTypes.string.isRequired +}; + +export default LinkGridItem; diff --git a/src/components/NavBar.js b/src/components/NavBar.js index 8d8cb3d..e9fafef 100644 --- a/src/components/NavBar.js +++ b/src/components/NavBar.js @@ -42,15 +42,6 @@ const useStyles = makeStyles(theme => ({ width: 'auto' } }, - searchIcon: { - width: theme.spacing(7), - height: '100%', - position: 'absolute', - pointerEvents: 'none', - display: 'flex', - alignItems: 'center', - justifyContent: 'center' - }, inputRoot: { color: 'inherit' }, @@ -173,7 +164,7 @@ const NavBar = () => { > - + Ethodoxy diff --git a/src/components/useAxiosGet.js b/src/components/useAxiosGet.js new file mode 100644 index 0000000..64f13d1 --- /dev/null +++ b/src/components/useAxiosGet.js @@ -0,0 +1,19 @@ +// eslint-disable-next-line no-unused-vars +import React, { useState, useEffect } from 'react'; + +import axios from 'axios'; +import { default_headers } from '../constants'; + +const useAxiosGet = url => { + const [ data, setData ] = useState(null); + const getData = async () => { + const config = { headers: { ...default_headers }}; + const resp = await axios.get(url, config); + const json = resp.json(); + setData(json); + }; + useEffect(() => { getData(url); [url];}); + return data; +}; + +export default useAxiosGet; diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 0000000..9320666 --- /dev/null +++ b/src/constants.js @@ -0,0 +1,9 @@ +export const BASE_URL = 'https://ethodoxy.herokuapp.com/api/v1'; +export const DR_BOOKS_URL = `${BASE_URL}/books/`; + +export const default_headers = { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'PUT, GET, PATCH, POST', + 'Access-Control-Allow-Headers': 'Content-Type', + 'Access-Control-Max-Age': '3000', +}; diff --git a/src/index.css b/src/index.css index 20abd54..08ca427 100644 --- a/src/index.css +++ b/src/index.css @@ -12,9 +12,9 @@ body { -moz-osx-font-smoothing: grayscale; } -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", - monospace; +a { + text-decoration: none; + color: #1E3B9E; } #root { @@ -44,7 +44,17 @@ code { min-height: 100vh; } +.book-link { + padding: 10px; + border-radius: 5px; + font-weight: bold; + background: #F5F5F6; + display: block; + width: 100%; +} + footer { text-align: center; background: #f5f5f5; + margin-top: 30px; } diff --git a/src/reducers/authUser.js b/src/reducers/authUser.js index be1d4f6..21ab668 100644 --- a/src/reducers/authUser.js +++ b/src/reducers/authUser.js @@ -1,6 +1,6 @@ -import { SET_AUTH_USER } from '../actions/constants'; +import { SET_AUTH_USER } from '../actions/actions.types'; -export const auth = (state = 'AUTH_USER_ID', action) => { +const auth = (state = 'AUTH_USER_ID', action) => { switch (action.type) { case SET_AUTH_USER: return action.id; @@ -8,3 +8,5 @@ export const auth = (state = 'AUTH_USER_ID', action) => { return state; } }; + +export default auth; diff --git a/src/reducers/drbReducer.js b/src/reducers/drbReducer.js new file mode 100644 index 0000000..94e19de --- /dev/null +++ b/src/reducers/drbReducer.js @@ -0,0 +1,16 @@ +import { GET_DRB_BOOKS } from '../actions/actions.types'; + +const drbReducer = (state = {}, action) => { + // console.log('action ....', action); + switch(action.type) { + case GET_DRB_BOOKS: + return { + ...state, + books: action.booklist + }; + default: + return state; + } +}; + +export default drbReducer; diff --git a/src/reducers/rootReducer.js b/src/reducers/rootReducer.js index 3b5d345..c587d24 100644 --- a/src/reducers/rootReducer.js +++ b/src/reducers/rootReducer.js @@ -1,8 +1,9 @@ import { combineReducers } from 'redux'; -import { auth } from './authUser'; +import auth from './authUser'; +import drbReducer from './drbReducer'; const rootReducer = combineReducers({ - auth + auth, drbReducer, }); export default rootReducer; diff --git a/yarn.lock b/yarn.lock index 77b00f3..cc3b857 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2010,6 +2010,14 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== +axios@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" + integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ== + dependencies: + follow-redirects "1.5.10" + is-buffer "^2.0.2" + axobject-query@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9" @@ -3270,6 +3278,13 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6. dependencies: ms "2.0.0" +debug@=3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + debug@^3.2.5, debug@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" @@ -4294,6 +4309,13 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + follow-redirects@^1.0.0: version "1.7.0" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.7.0.tgz#489ebc198dc0e7f64167bd23b03c4c19b5784c76" @@ -5174,6 +5196,11 @@ is-buffer@^1.0.2, is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-buffer@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" + integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== + is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" @@ -8187,7 +8214,7 @@ prompts@^2.0.1: kleur "^3.0.2" sisteransi "^1.0.0" -prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.6, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -8422,6 +8449,13 @@ react-loader-spinner@^2.3.0: babel-runtime "^6.26.0" prop-types "^15.6.2" +react-redux-loading@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/react-redux-loading/-/react-redux-loading-1.0.1.tgz#b03685c6c0304681b3097a27a3e6ee9b534fd699" + integrity sha512-FXEW1fCU7yeJHDuJ1OTG3VUHtllpw6ezenVVl/b64f25MCxd9Vsnm+N/4g5/rx89/FGGr+IMMVO3cpLhvxqLTw== + dependencies: + prop-types "^15.5.6" + react-redux@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.1.0.tgz#72af7cf490a74acdc516ea9c1dd80e25af9ea0b2" @@ -9213,6 +9247,11 @@ slice-ansi@^2.1.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" +slugify@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.3.4.tgz#78d2792d7222b55cd9fc81fa018df99af779efeb" + integrity sha512-KP0ZYk5hJNBS8/eIjGkFDCzGQIoZ1mnfQRYS5WM3273z+fxGWXeN0fkwf2ebEweydv9tioZIHGZKoF21U07/nw== + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -9783,6 +9822,11 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.2: resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== +titlecase@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/titlecase/-/titlecase-1.1.3.tgz#fc6d65ff582b0602410768ef1a09b70506313dc3" + integrity sha512-pQX4oiemzjBEELPqgK4WE+q0yhAqjp/yzusGtlSJsOuiDys0RQxggepYmo0BuegIDppYS3b3cpdegRwkpyN3hw== + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"