Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions client/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 <div>ERROR: {props.unknownError.message}. Please contact support.</div>
}
if (props.unauthenticatedError) {
return <Login/>
}
*/
return (
<div>
<Navbar />
<Routes />
{props.unknownError ? <div>Error</div> : <Routes/>}
</div>
)
}

export default App
const mapState = (state) => {
return { unknownError: state.error.unknownError }
}

export default connect(mapState, undefined)(App)
3 changes: 2 additions & 1 deletion client/components/EditProduct.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
4 changes: 4 additions & 0 deletions client/components/home-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
7 changes: 6 additions & 1 deletion client/store/categories.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
25 changes: 24 additions & 1 deletion client/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -20,7 +42,8 @@ const reducer = combineReducers({
categories,
cart,
orders,
reviews
reviews,
error: errorReducer,
})

const middleware = composeWithDevTools(
Expand Down
1 change: 1 addition & 0 deletions client/store/orders.js
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
4 changes: 4 additions & 0 deletions server/api/orders.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
60 changes: 58 additions & 2 deletions server/api/products.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down