From 50e2dc54220d7690f4c0e789307d3a3d2ce188f1 Mon Sep 17 00:00:00 2001 From: Emily McCarthy Date: Mon, 31 Jul 2017 17:00:51 -0400 Subject: [PATCH] Categories routes and components not yet filterable --- client/Routes.js | 9 +- client/components/AllCategories.js | 46 +++++++++ client/components/AllCharacters.js | 3 +- client/components/FilteredCharacters.js | 119 ++++++++++++++++++++++++ client/components/Main.js | 1 + client/components/index.js | 2 + client/store/allCategories.js | 35 +++++++ client/store/filteredCharacters.js | 0 client/store/index.js | 6 +- client/store/searchTerms.js | 44 +++++++++ client/store/singleCategory.js | 35 +++++++ server/api/categories.js | 27 ++++++ server/api/characters.js | 10 +- server/api/index.js | 1 + server/db/models/category.js | 4 + server/db/models/index.js | 8 +- 16 files changed, 338 insertions(+), 12 deletions(-) create mode 100644 client/components/AllCategories.js create mode 100644 client/components/FilteredCharacters.js create mode 100644 client/store/filteredCharacters.js create mode 100644 client/store/searchTerms.js create mode 100644 server/api/categories.js diff --git a/client/Routes.js b/client/Routes.js index ca70843..9d70cef 100644 --- a/client/Routes.js +++ b/client/Routes.js @@ -4,8 +4,8 @@ import { Router } from 'react-router' import { Route, Switch } from 'react-router-dom' import PropTypes from 'prop-types' import history from './history' -import {Main, Login, Signup, UserHome, AllCharacters, SingleCharacter} from './components' -import {me, fetchCharacters} from './store'; +import {Main, Login, Signup, UserHome, AllCharacters, SingleCharacter, AllCategories, SingleCategory, FilteredCharacters} from './components' +import {me, fetchCharacters, fetchCategories} from './store'; /** * COMPONENT @@ -30,7 +30,9 @@ class Routes extends Component { - + + + { isLoggedIn ? @@ -65,6 +67,7 @@ const mapDispatch = (dispatch) => { loadInitialData () { dispatch(me()); dispatch(fetchCharacters()); + dispatch(fetchCategories()); } } diff --git a/client/components/AllCategories.js b/client/components/AllCategories.js new file mode 100644 index 0000000..04f26fb --- /dev/null +++ b/client/components/AllCategories.js @@ -0,0 +1,46 @@ +import React, { Component } from 'react'; +import { withRouter, Link } from 'react-router-dom'; +import { connect } from 'react-redux'; +import { Card, FlexParent, CharacterImg, CardText, Title } from './component-styles' + +// export const AllCharacters = (props) => { +// console.log("PRINT", props); +// return (

hi

) +// } + +class AllCategories extends Component { + constructor(props) { + super(props); + + this.state = { + tag: '' + }; + } + render() { + const allCategories = this.props.allCategories; + console.log("Categories", this.props); + return ( + + CATEGORIES + +
    + { + allCategories.map(category => { + return ( +
  • {category.tag}
  • + ) + }) + } +
+
+
+ + ); + } +} +/* ----------------- CONTAINER ------------------ */ +const mapStateToProps = ({ allCategories}) => ({ allCategories }); + +export default withRouter(connect(mapStateToProps)(AllCategories)); + +// export default AllCharacters; diff --git a/client/components/AllCharacters.js b/client/components/AllCharacters.js index 2a3a22d..2e338d7 100644 --- a/client/components/AllCharacters.js +++ b/client/components/AllCharacters.js @@ -2,7 +2,7 @@ import React, { Component } from 'react'; import { withRouter, Link } from 'react-router-dom'; import { connect } from 'react-redux'; import { Card, FlexParent, CharacterImg, CardText, Title } from './component-styles' - +import AllCategories from './AllCategories'; // export const AllCharacters = (props) => { // console.log("PRINT", props); // return (

hi

) @@ -24,6 +24,7 @@ class AllCharacters extends Component { return ( BROWSE CHARACTERS + { allCharacters.map(character => { diff --git a/client/components/FilteredCharacters.js b/client/components/FilteredCharacters.js new file mode 100644 index 0000000..b1b7f35 --- /dev/null +++ b/client/components/FilteredCharacters.js @@ -0,0 +1,119 @@ +import React, { Component } from 'react'; +import { withRouter, Link } from 'react-router-dom'; +import { connect } from 'react-redux'; +import { Card, FlexParent, CharacterImg, CardText, Title } from './component-styles' +import AllCategories from './AllCategories'; +import {addSearchTerm, fetchCharacters, fetchCategoryForFilter} from '../store'; + + + +class FilteredCharacters extends Component { + constructor(props) { + super(props); + + this.state = { + filtered: [], + + }; + + this.handleClick = this.handleClick.bind(this); + } + +componentDidMount() { + } + + handleClick(evt){ + + console.log(evt.target.value, "event.target.value - categoryId"); + this.props.AddSearchTerms(evt.target.value) + } + render() { + + const allCharacters = this.props.allCharacters; + const allCategories = this.props.allCategories; + const CategorySet = [...new Set(allCategories)]; + const filtered = allCharacters.filter(function(character){ + const tags = character.tags; + const bool = true; + + console.log(check, "check"); + return bool; + }) + + console.log("CHARACTERS", this.props); + return ( + + BROWSE CHARACTERS + { + allCategories.map(category => { + return () + }) + } + + + { + allCharacters.map(character => { + return ( + + + + + + {character.name} + + {character.price} + + + + ); + }) + } + + + FILTERED CHARACTERS + + { + allCharacters.map(character => { + return ( + + + + + + {character.name} + + {character.price} + + + + ); + }) + } + + + + ); + } +} + +/* ----------------- CONTAINER ------------------ */ + + + +const mapStateToProps = ({allCharacters, allCategories}) => ({allCharacters, allCategories}); +const mapDispatchToProps = (dispatch) => { + return { + AddSearchTerms (categoryId) { + dispatch(fetchCategoryForFilter(categoryId)); + }, + + loadCharacters(){ + dispatch(fetchCharacters); + + } + } + + } + +export default withRouter(connect(mapStateToProps, mapDispatchToProps)(FilteredCharacters)); + diff --git a/client/components/Main.js b/client/components/Main.js index f70ce14..d36d8cb 100644 --- a/client/components/Main.js +++ b/client/components/Main.js @@ -6,6 +6,7 @@ import { withRouter, Link } from 'react-router-dom' import { logout } from '../store' import AllCharacters from './AllCharacters' import SingleCharacter from './SingleCharacter'; +import AllCategories from './AllCategories'; import { Wrapper, Header, Title, StyledLink, Menu } from './component-styles' diff --git a/client/components/index.js b/client/components/index.js index b6494f1..e7b3ebf 100644 --- a/client/components/index.js +++ b/client/components/index.js @@ -8,3 +8,5 @@ export {default as UserHome} from './user-home' export {Login, Signup} from './auth-form'; export {default as AllCharacters} from './AllCharacters'; export {default as SingleCharacter} from './SingleCharacter'; +export {default as AllCategories} from './AllCategories'; +export {default as FilteredCharacters } from './FilteredCharacters'; \ No newline at end of file diff --git a/client/store/allCategories.js b/client/store/allCategories.js index e69de29..71d4bf5 100644 --- a/client/store/allCategories.js +++ b/client/store/allCategories.js @@ -0,0 +1,35 @@ +import axios from 'axios'; + +/* ----------------- ACTION TYPES ------------------ */ + +const ALL_CATEGORIES = 'ALL_CATEGORIES'; + +/* ------------ ACTION CREATORS ------------------ */ + +export function getCategories(categories) { + const action = { type: ALL_CATEGORIES, categories }; + return action; +} + +/* ------------ REDUCER ------------------ */ + +export default function reducer (categories = [], action) { + switch (action.type) { + + case ALL_CATEGORIES: + return action.categories; + default: + return categories; + } +} + + +/* ------------ THUNK CREATORS ------------------ */ + +export const fetchCategories = () => dispatch => { + axios.get('/api/categories') + .then(res => { + dispatch(getCategories(res.data)); + }); + +}; diff --git a/client/store/filteredCharacters.js b/client/store/filteredCharacters.js new file mode 100644 index 0000000..e69de29 diff --git a/client/store/index.js b/client/store/index.js index 425a99d..f904ceb 100644 --- a/client/store/index.js +++ b/client/store/index.js @@ -7,9 +7,10 @@ import singleCharacter from './singleCharacter'; import cart from './cart'; import allCategories from './allCategories'; import singleCategory from './singleCategory'; +import filteredCharacters from './filteredCharacters.js'; +import searchTerms from './searchTerms.js'; - -const reducer = combineReducers({user, allCharacters, singleCharacter, cart}); +const reducer = combineReducers({user, allCharacters, singleCharacter, cart, allCategories, singleCategory, searchTerms}); const middleware = applyMiddleware(thunkMiddleware, createLogger({collapsed: true})); const store = createStore(reducer, middleware); @@ -20,3 +21,4 @@ export * from './singleCharacter'; export * from './cart'; export * from './allCategories'; export * from './singleCategory'; +export * from './searchTerms'; \ No newline at end of file diff --git a/client/store/searchTerms.js b/client/store/searchTerms.js new file mode 100644 index 0000000..28d194d --- /dev/null +++ b/client/store/searchTerms.js @@ -0,0 +1,44 @@ +import axios from 'axios'; + +/* ----------------- ACTION TYPES ------------------ */ + +export const ADD_SEARCH_TERM = 'ADD_SEARCH_TERM'; +export const REMOVE_SEARCH_TERM = 'REMOVE_SEARCH_TERM'; + + +/* ------------ ACTION CREATORS ------------------ */ + +export function addSearchTerm(category) { + const action = { type: ADD_SEARCH_TERM, category }; + return action; +} + +export function removeSearchTerm(category) { + const action = { type: REMOVE_SEARCH_TERM, category}; + return action; +} +/* ------------ REDUCER ------------------ */ + +export default function reducer (searchTerms = [], action) { + switch (action.type) { + + case ADD_SEARCH_TERM: + return [action.category, ...searchTerms]; + case REMOVE_SEARCH_TERM: + return searchTerms.filter(searchTerm => searchTerm.id !== action.category.id); + default: + return searchTerms; + } +} + + +/* ------------ THUNK CREATORS ------------------ */ + + +export const fetchCategoryForFilter = (categoryId) => dispatch => { + axios.get(`/api/categories/${categoryId}`) + .then(res => { + dispatch(addSearchTerm(res.data)); + }); + +}; diff --git a/client/store/singleCategory.js b/client/store/singleCategory.js index e69de29..d915d0c 100644 --- a/client/store/singleCategory.js +++ b/client/store/singleCategory.js @@ -0,0 +1,35 @@ +import axios from 'axios'; + +/* ----------------- ACTION TYPES ------------------ */ + +const SINGLE_CATEGORY = 'SINGLE_CATEGORY'; + +/* ------------ ACTION CREATORS ------------------ */ + +export function getSingleCategory(category) { + const action = { type: SINGLE_CATEGORY, category }; + return action; +} + +/* ------------ REDUCER ------------------ */ + +export default function reducer (category = {}, action) { + switch (action.type) { + + case SINGLE_CATEGORY: + return action.category; + default: + return category; + } +} + + +/* ------------ THUNK CREATORS ------------------ */ + +export const fetchCategory = (categoryId) => dispatch => { + axios.get(`/api/categories/${categoryId}`) + .then(res => { + dispatch(getSingleCategory(res.data)); + }); + +}; diff --git a/server/api/categories.js b/server/api/categories.js new file mode 100644 index 0000000..1d6a8be --- /dev/null +++ b/server/api/categories.js @@ -0,0 +1,27 @@ +'use strict'; + +const express = require('express'); +const router = express.Router(); +const models = require('../db/models'); +const Category = models.Category; +const ProductCategory = models.ProductCategory; +const Character = models.Character; + + +module.exports = router; + +// EI: don't forget about query strings! +router.get('/', function (req, res, next) { + Category.findAll() + .then(category => res.json(category)) + .catch(next); + +}); + + +router.get('/:categoryId', function (req, res, next) { + Category.findOne({ where: {id: req.params.categoryId}, include: {model: Character, as: "products"}}) + .then(category => res.json(category)) + .catch(next); +}); + diff --git a/server/api/characters.js b/server/api/characters.js index b220436..74d8d59 100644 --- a/server/api/characters.js +++ b/server/api/characters.js @@ -4,13 +4,13 @@ const express = require('express'); const router = express.Router(); const models = require('../db/models'); const Character = models.Character; - +const Category = models.Category; module.exports = router; // EI: don't forget about query strings! router.get('/', function (req, res, next) { - Character.findAll() + Character.findAll({include: {model: Category, as: "tags"}}) .then(character => res.json(character)) .catch(next); @@ -23,3 +23,9 @@ router.get('/:characterId', function (req, res, next) { .catch(next); }); +router.get('/:characterId/categories', function (req, res, next){ + Character.findOne({ where: {id: req.params.characterId}, include: {model: Category, as: "tags"}}) + .then(character => res.json(character.tags)) + .catch(next); +}); + diff --git a/server/api/index.js b/server/api/index.js index 2ff6e6b..659e5ff 100644 --- a/server/api/index.js +++ b/server/api/index.js @@ -4,6 +4,7 @@ module.exports = router; router.use('/users', require('./users')); router.use('/characters', require('./characters')); router.use('/orders', require('./orders')); +router.use('/categories', require('./categories')); router.use((req, res, next) => { const error = new Error('Not Found'); diff --git a/server/db/models/category.js b/server/db/models/category.js index c20f37c..930c5ad 100644 --- a/server/db/models/category.js +++ b/server/db/models/category.js @@ -6,6 +6,10 @@ const Category = db.define('category', { tag: { type: Sequelize.STRING, } + }, { + scopes: { + + } }); module.exports = Category; diff --git a/server/db/models/index.js b/server/db/models/index.js index 6707fa7..320bfc4 100644 --- a/server/db/models/index.js +++ b/server/db/models/index.js @@ -24,12 +24,12 @@ const Character = require('./character.js'); User.hasMany(Order); Order.hasMany(OrderItems); -Movie.hasMany(Character); -Character.belongsTo(Movie); +//Movie.hasMany(Character); +//Character.belongsTo(Movie); Review.belongsTo(User); Review.belongsTo(Character); -Character.belongsToMany(Category, { through: ProductCategory}) -Category.hasMany(Character) +Character.belongsToMany(Category, {as: 'tags', through: ProductCategory, foreignKey: 'characterId'}) +Category.belongsToMany(Character, {as: 'products', through: ProductCategory, foreignKey: 'categoryId'}) module.exports = { User,