diff --git a/client/app.js b/client/app.js
index 2dc72eb..4ef0fdf 100644
--- a/client/app.js
+++ b/client/app.js
@@ -3,13 +3,25 @@ import React from 'react'
import {Navbar} from './components'
import Routes from './routes'
-const App = () => {
+const App = (props) => {
+ /*
+ if (props.unknownError) {
+ return
ERROR: {props.unknownError.message}. Please contact support.
+ }
+ if (props.unauthenticatedError) {
+ return
+ }
+ */
return (
-
+ {props.unknownError ?
Error
:
}
)
}
-export default App
+const mapState = (state) => {
+ return { unknownError: state.error.unknownError }
+}
+
+export default connect(mapState, undefined)(App)
diff --git a/client/components/EditProduct.js b/client/components/EditProduct.js
index f1b61c1..bcfeaf6 100644
--- a/client/components/EditProduct.js
+++ b/client/components/EditProduct.js
@@ -141,7 +141,8 @@ const mapDispatchToProps = (dispatch, ownProps) => ({
const mapStateToProps = (state, ownProps) => {
return {
selectedProduct: state.products.selectedProduct,
- isAdmin: state.currentUser.isAdmin
+ isAdmin: state.currentUser.isAdmin,
+ badRequest: state.error.badRequest
}
}
diff --git a/client/components/home-page.js b/client/components/home-page.js
index d32abae..2da4295 100644
--- a/client/components/home-page.js
+++ b/client/components/home-page.js
@@ -13,6 +13,10 @@ import {
Pagination
} from 'semantic-ui-react'
+// GET /products
+// state.products = [/* all the products */]
+
+// REVIEW: how large is allProducts
const ProductsOnCurPage = (allProducts, curPage, itemsPerPage) => {
return allProducts.slice(
(curPage - 1) * itemsPerPage,
diff --git a/client/store/categories.js b/client/store/categories.js
index 670af10..43a852d 100644
--- a/client/store/categories.js
+++ b/client/store/categories.js
@@ -9,19 +9,24 @@ const getCategories = categories => ({
categories
})
+const error = error => ({ type: 'ERROR', error })
+
// Initial State
const initialState = []
+
// Thunk Creators
export const fetchCategories = () => async dispatch => {
try {
const {data} = await axios.get('/api/products/categories')
dispatch(getCategories(data))
} catch (error) {
- console.log(error)
+ dispatch(error(error))
}
}
+// REVIEW: discuss alternate patterns for reducer cases
+// and the value of consistency
const dispatchers = {
[GET_CATEGORIES]: (state, action) => action.categories
}
diff --git a/client/store/index.js b/client/store/index.js
index bf8c955..991b488 100644
--- a/client/store/index.js
+++ b/client/store/index.js
@@ -12,6 +12,28 @@ import storage from 'redux-persist/lib/storage'
import autoMergeLevel2 from 'redux-persist/es/stateReconciler/autoMergeLevel2'
import orders from './orders'
import reviews from './reviews'
+//import errors from './errors'
+
+function errorReducer (state={}, action) {
+ if (action.type === GET_USER) return { ...state, unauthenticatedError: undefined }
+ if (action.type !== 'ERROR') return state
+
+ const error = action.error;
+ if (error.response && error.response.status) {
+ if (error.response.status === 401) {
+ return {...state, unauthenticatedError: error }
+ }
+ else if (error.response.status === 403) {
+ return {...state, unauthorizedError: error }
+ }
+ else if (error.response.status === 400) {
+ return {...state, badRequest: error }
+ }
+ }
+ if (error) {
+ return {...state, unknownError: error}
+ }
+}
const reducer = combineReducers({
users,
@@ -20,7 +42,8 @@ const reducer = combineReducers({
categories,
cart,
orders,
- reviews
+ reviews,
+ error: errorReducer,
})
const middleware = composeWithDevTools(
diff --git a/client/store/orders.js b/client/store/orders.js
index 6187e68..d64de12 100644
--- a/client/store/orders.js
+++ b/client/store/orders.js
@@ -19,6 +19,7 @@ export const editOrder = updatedOrder => ({type: EDIT_ORDER, updatedOrder})
// THUNK-TIONS
export const fetchOrders = () => {
+ // REVIEW: gotta handle errors
return async dispatch => {
const {data} = await axios.get('/api/orders')
dispatch(setOrders(data))
diff --git a/server/api/orders.js b/server/api/orders.js
index 0b8e7bc..b7b8e07 100644
--- a/server/api/orders.js
+++ b/server/api/orders.js
@@ -18,6 +18,10 @@ router.get('/', adminCheckMiddleware, async (req, res, next) => {
// Associated non-admin User instance should also have access to these specific routes
+// REVIEW:
+// GET /orders/user/:userId
+// vs
+// GET /users/:userId/orders
router.get('/user/:userId', loginCheckMiddleware, async (req, res, next) => {
try {
const whichOrders = await Order.findAll({
diff --git a/server/api/products.js b/server/api/products.js
index b849c5c..723eb3d 100644
--- a/server/api/products.js
+++ b/server/api/products.js
@@ -5,15 +5,71 @@ module.exports = router
// All users can view all products and product by id
+// PUBLIC api
+// - no matter who requests this endpoint
+// - no matter when they request this endpoint
+// - everybody should see tha same data
+// - based purely on the url (include query string)
+//
+// GET /products?page=2&category=sharpeners
+// [...]
+//
+// GET /products?page=2&category=sharpeners
+// [...]
+//
+// PRIVATE api
+// - only some people CAN request this
+// - different people get different data back
+//
+// GET /me
+// { name: 'collin' }
+// { name: 'finn' }
router.get('/', async (req, res, next) => {
try {
- const allProducts = await Product.findAll({include: [Category]})
- res.json(allProducts)
+ // GET /products?page=2
+ const page = req.query.page || 1
+ const perPage = 10
+ const currentPage = 1
+ const offset = (currentPage - 1) * perPage;
+ // select * from products limit 10 offset ${offset} order by updateAt desc
+ // REVIEW: pagination
+ const pageOfProducts = await Product.findAll({
+ include: [{model: Category, fields: ['title']}],
+ limit: perPage,
+ offset: offset,
+ orderBy: 'updatedAt desc'
+ })
+ res.json(pageOfProducts)
} catch (err) {
next(err)
}
})
+// includes
+// home page
+// - list of products
+// - prints title, image, price, category
+//
+// short-list
+// - bullett list of title
+//
+// GET /products?page=1&category=sharpeners&include[]=Category&CategoryFields[]=title&CategoryFields[]=id
+// GraphQL
+// const query = `
+// query {
+// products {
+// id
+// title
+// price
+// categories {
+// id
+// name
+// }
+// }
+// `
+// const result = await runGraphQL(query)
+// result.data.products[0].categories[0].name
+
router.get('/categories', async (req, res, next) => {
try {
const allCategories = await Category.findAll()