diff --git a/package-lock.json b/package-lock.json index 75cd8e0..7928e8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12716,6 +12716,11 @@ "symbol-observable": "^1.2.0" } }, + "redux-devtools-extension": { + "version": "2.13.8", + "resolved": "https://registry.npmjs.org/redux-devtools-extension/-/redux-devtools-extension-2.13.8.tgz", + "integrity": "sha512-8qlpooP2QqPtZHQZRhx3x3OP5skEV1py/zUdMY28WNAocbafxdG2tRD1MWE7sp8obGMNYuLWanhhQ7EQvT1FBg==" + }, "redux-thunk": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", diff --git a/package.json b/package.json index 1e509b2..f7c765b 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "react-router-dom": "^5.2.0", "react-scripts": "3.4.3", "redux": "^4.0.5", + "redux-devtools-extension": "^2.13.8", "redux-thunk": "^2.3.0" }, "scripts": { diff --git a/src/App.js b/src/App.js index b934655..0af851e 100644 --- a/src/App.js +++ b/src/App.js @@ -22,11 +22,12 @@ class App extends Component { { - console.log("PlacesContainer is being rendered"); return ( ); }} @@ -34,11 +35,10 @@ class App extends Component { { - console.log("AncestryGroupsContainer is being rendered"); return ( ); }} @@ -55,7 +55,8 @@ class App extends Component { const mapStateToProps = (state) => { return { places: state.places, - ancestry_groups: state.ancestry_groups, + ancestryGroups: state.ancestryGroups, + placeAncestryGroups: state.placeAncestryGroups, }; }; const mapDispatchToProps = (dispatch) => { diff --git a/src/actions/placeActions.js b/src/actions/placeActions.js index 7116d44..a70e63a 100644 --- a/src/actions/placeActions.js +++ b/src/actions/placeActions.js @@ -8,24 +8,12 @@ export const fetchPlaces = () => { .then((json) => { dispatch({ type: "ADD_PLACES", places: json.data }); }); - // .then(data => { - // for (const key in data) { - // places.push({name: data[key]["attributes"]["name"], - // population: data[key]["attributes"]["population"], - // percent_german: data[key]["attributes"]["percent_german"], - // percent_african_american: data[key]["attributes"]["percent_african_american"], - // percent_mexican: data[key]["attributes"]["percent_mexican"] - // }) - // } }; }; export const addPlace = (place) => { return (dispatch) => { dispatch({ type: "POSTING_PLACE" }); - console.log(`in addPlace action`); - console.log(dispatch); - console.log(place); fetch("http://localhost:3000/api/v1/places", { method: "POST", headers: { "Content-Type": "application/json" }, @@ -46,7 +34,11 @@ export const fetchAncestryGroups = () => { return response.json(); }) .then((json) => { - dispatch({ type: "ADD_ANCESTRY_GROUPS", ancestry_groups: json.data }); + dispatch({ type: "ADD_ANCESTRY_GROUPS", ancestryGroups: json.data }); + dispatch({ + type: "ADD_PLACE_ANCESTRY_GROUPS", + ancestryGroups: json.data, + }); }); }; }; diff --git a/src/components/ancestry_groups/AncestryGroup.js b/src/components/ancestry_groups/AncestryGroup.js index 2852cc7..a986bb7 100644 --- a/src/components/ancestry_groups/AncestryGroup.js +++ b/src/components/ancestry_groups/AncestryGroup.js @@ -5,31 +5,40 @@ const AncestryGroup = (props) => { console.log(props); let { ancestryGroupId } = useParams(); console.log(useParams()); - const ancestry_group = props.ancestry_groups[ancestryGroupId - 1]; - const places = ancestry_group.attributes.place_ancestry_groups; - places.sort((a, b) => (a.attributes.percent < b.attributes.percent ? 1 : -1)); - const ancestryGroupCard = ancestry_group ? ( -
-

{ancestry_group.attributes.name}

-

- Population in the United States:{" "} - {ancestry_group.attributes.national_pop} -

- {places.map((place) => { - return ( -
-

- {place.attributes.place.name}: {place.attributes.percent}%,{" "} - {place.attributes.relative_to_national}x national average -

-
- ); - })} -
- ) : ( - "Place not found" - ); - return
{ancestryGroupCard}
; + if (props.ancestryGroups.length > 0) { + const ancestryGroup = props.ancestryGroups[ancestryGroupId - 1]; + const places = ancestryGroup.attributes.place_ancestry_groups; + places.sort((a, b) => + a.attributes.percent < b.attributes.percent ? 1 : -1 + ); + const ancestryGroupCard = ancestryGroup ? ( +
+

{ancestryGroup.attributes.name}

+

+ Population in the United States:{" "} + {ancestryGroup.attributes.national_pop} +

+ {places.map((place) => { + return ( +
+

+ {place.attributes.place.name}: {place.attributes.percent}%,{" "} + {place.attributes.relative_to_national}x national average +

+
+ ); + })} +
+ ) : ( + "Place not found" + ); + return
{ancestryGroupCard}
; + } else + return ( +
+

Loading, please wait.

+
+ ); }; export default AncestryGroup; diff --git a/src/components/ancestry_groups/AncestryGroups.js b/src/components/ancestry_groups/AncestryGroups.js index 250435a..270cd40 100644 --- a/src/components/ancestry_groups/AncestryGroups.js +++ b/src/components/ancestry_groups/AncestryGroups.js @@ -1,24 +1,33 @@ import React from "react"; import { Link } from "react-router-dom"; -const AncestryGroups = (props) => - props.ancestry_groups.map((ancestry_group) => { - console.log(props.ancestry_groups); +const AncestryGroups = (props) => { + if (props.ancestryGroups.length > 0) { + return props.ancestryGroups.map((ancestryGroup) => { + return ( +
+

+ + {ancestryGroup.attributes.name} + +

+

+ Percent of US Population:{" "} + {ancestryGroup.attributes.national_percent} +

+
+ ); + }); + } else { return ( -
-

- - {ancestry_group.attributes.name} - -

-

- Percent of US Population: {ancestry_group.attributes.national_percent} -

+
+

Loading, please wait.

); - }); + } +}; export default AncestryGroups; diff --git a/src/components/places/Place.js b/src/components/places/Place.js index fac86d0..4f665c5 100644 --- a/src/components/places/Place.js +++ b/src/components/places/Place.js @@ -2,32 +2,39 @@ import React from "react"; import { useParams } from "react-router-dom"; const Place = (props) => { - console.log(props); let { placeId } = useParams(); - const place = props.places[placeId - 1]; - console.log(place); - const groups = place.attributes.place_ancestry_groups; - groups.sort((a, b) => (a.attributes.percent < b.attributes.percent ? 1 : -1)); - const placeCard = place ? ( -
-

{place.attributes.name}

-

Population: {place.attributes.population}

- {groups.map((group) => { - console.log(group); - return ( -
-

- {group.attributes.ancestry_group.name}: {group.attributes.percent} - % -

-
- ); - })} -
- ) : ( - "Place not found" - ); - return
{placeCard}
; + if (props.places.length > 0) { + const place = props.places[placeId - 1]; + console.log(`place is ${place}`); + const groups = place.attributes.place_ancestry_groups; + groups.sort((a, b) => + a.attributes.percent < b.attributes.percent ? 1 : -1 + ); + const placeCard = place ? ( +
+

{place.attributes.name}

+

Population: {place.attributes.population}

+ {groups.map((group) => { + return ( +
+

+ {group.attributes.ancestry_group.name}:{" "} + {group.attributes.percent}% +

+
+ ); + })} +
+ ) : ( + "Place not found" + ); + return
{placeCard}
; + } else + return ( +
+

Loading, please wait.

+
+ ); }; export default Place; diff --git a/src/components/places/PlaceComparison.js b/src/components/places/PlaceComparison.js index 2759dd8..1f5c8db 100644 --- a/src/components/places/PlaceComparison.js +++ b/src/components/places/PlaceComparison.js @@ -3,32 +3,36 @@ import { useParams } from "react-router-dom"; const PlaceComparison = (props) => { let { placeId } = useParams(); - const place = props.places[placeId - 1]; - const groups = place.attributes.place_ancestry_groups; - groups.sort((a, b) => - a.attributes.relative_to_national < b.attributes.relative_to_national - ? 1 - : -1 - ); - const placeCard = place ? ( -
-

Relative representation of groups

-

(times the national average)

- {groups.map((group) => { - return ( -
-

- {group.attributes.ancestry_group.name}:{" "} - {group.attributes.relative_to_national} -

-
- ); - })} -
- ) : ( - "Place not found" - ); - return
{placeCard}
; + if (props.places.length > 0) { + const place = props.places[placeId - 1]; + const groups = place.attributes.place_ancestry_groups; + groups.sort((a, b) => + a.attributes.relative_to_national < b.attributes.relative_to_national + ? 1 + : -1 + ); + const placeCard = place ? ( +
+

Relative representation of groups

+

(times the national average)

+ {groups.map((group) => { + return ( +
+

+ {group.attributes.ancestry_group.name}:{" "} + {group.attributes.relative_to_national} +

+
+ ); + })} +
+ ) : ( + "Place not found" + ); + return
{placeCard}
; + } else { + return null; + } }; export default PlaceComparison; diff --git a/src/components/places/PlaceInput.js b/src/components/places/PlaceInput.js index 18877a1..4dac5e9 100644 --- a/src/components/places/PlaceInput.js +++ b/src/components/places/PlaceInput.js @@ -1,6 +1,6 @@ import React, { Component } from "react"; import { connect } from "react-redux"; -import { addPlace } from "../../actions/placeActions"; +import { addPlace, fetchAncestryGroups } from "../../actions/placeActions"; class PlaceInput extends Component { constructor(props) { @@ -8,6 +8,7 @@ class PlaceInput extends Component { this.state = { name: "", population: 0, + placeAncestryGroups: null, }; } @@ -19,21 +20,56 @@ class PlaceInput extends Component { handlePopulationChange = (event) => { this.setState({ - population: event.target.value, + population: parseInt(event.target.value), }); }; + handleGroupChange = (groups, id, event) => { + // debugger; + let group = { ...groups[id] }; + group.population = parseInt(event.target.value); + groups[id] = group; + this.setState({ + placeAncestryGroups: groups, + }); + console.log(this.state); + }; handleSubmit = (e) => { e.preventDefault(); let formData = { name: this.state.name, population: this.state.population, + place_ancestry_groups_attributes: this.state.placeAncestryGroups.map( + (group) => { + return { + ancestry_group_id: parseInt(group.ancestryGroupId), + population: group.population, + }; + } + ), }; - console.log(formData); + console.log(this.props); this.props.addPlace(formData); + this.props.fetchAncestryGroups(); + const placeAncestryGroups = this.state.placeAncestryGroups.map((group) => { + return { ...group, population: 0 }; + }); + this.setState({ + name: "", + population: 0, + placeAncestryGroups, + }); }; render() { + let groups; + if (this.state.placeAncestryGroups) { + groups = [...this.state.placeAncestryGroups]; + } else if (this.props.placeAncestryGroups) { + groups = [...this.props.placeAncestryGroups]; + } else { + groups = []; + } return (
+ {groups.map((group) => { + return ( +
+ +
+ ); + })}
@@ -77,6 +135,7 @@ class PlaceInput extends Component { const mapDispatchToProps = (dispatch) => { return { addPlace: (place) => dispatch(addPlace(place)), + fetchAncestryGroups: () => dispatch(fetchAncestryGroups()), }; }; export default connect(null, mapDispatchToProps)(PlaceInput); diff --git a/src/components/places/Places.js b/src/components/places/Places.js index bee3b93..882674b 100644 --- a/src/components/places/Places.js +++ b/src/components/places/Places.js @@ -1,19 +1,27 @@ import React from "react"; import { Link } from "react-router-dom"; -const Places = (props) => - props.places.map((place) => { - console.log(props.places); +const Places = (props) => { + if (props.places.length > 0) { + return props.places.map((place) => { + return ( +
+

+ + {place.attributes.name} + +

+

Population: {place.attributes.population}

+
+ ); + }); + } else { return ( -
-

- - {place.attributes.name} - -

-

Population: {place.attributes.population}

+
+

Loading, please wait.

); - }); + } +}; export default Places; diff --git a/src/containers/AncestryGroupsContainer.js b/src/containers/AncestryGroupsContainer.js index c73bda8..8e58902 100644 --- a/src/containers/AncestryGroupsContainer.js +++ b/src/containers/AncestryGroupsContainer.js @@ -6,18 +6,15 @@ import AncestryGroup from "../components/ancestry_groups/AncestryGroup.js"; class AncestryGroupsContainer extends Component { render() { - const ancestry_groups = this.props.ancestry_groups; + const ancestryGroups = this.props.ancestryGroups; return (
- + - {/* - - */} - +
@@ -26,7 +23,7 @@ class AncestryGroupsContainer extends Component { } const mapStateToProps = (state) => { - return { ancestry_groups: state.ancestry_groups }; + return { ancestryGroups: state.ancestryGroups }; }; export default connect(mapStateToProps)(AncestryGroupsContainer); diff --git a/src/containers/PlacesContainer.js b/src/containers/PlacesContainer.js index 26bec62..9519630 100644 --- a/src/containers/PlacesContainer.js +++ b/src/containers/PlacesContainer.js @@ -9,20 +9,14 @@ import PlaceInput from "../components/places/PlaceInput"; class PlacesContainer extends Component { render() { const places = this.props.places; + console.log(places); + const placeAncestryGroups = this.props.placeAncestryGroups; return (
- + - {/* { - console.log("should redirect to Place"); - return ; - }} - /> */} diff --git a/src/index.js b/src/index.js index 3970661..66f398a 100644 --- a/src/index.js +++ b/src/index.js @@ -8,8 +8,18 @@ import { Provider } from "react-redux"; import { createStore, applyMiddleware } from "redux"; import thunk from "redux-thunk"; import placesReducer from "./reducers/placesReducer.js"; +import { composeWithDevTools } from "redux-devtools-extension"; -const store = createStore(placesReducer, applyMiddleware(thunk)); +const composeEnhancers = composeWithDevTools({ + // Specify name here, actionsBlacklist, actionsCreators and other options if needed +}); +const store = createStore( + placesReducer, + /* preloadedState, */ composeEnhancers( + applyMiddleware(thunk) + // other store enhancers if any + ) +); ReactDOM.render( diff --git a/src/reducers/placesReducer.js b/src/reducers/placesReducer.js index 663dc75..5b5f520 100644 --- a/src/reducers/placesReducer.js +++ b/src/reducers/placesReducer.js @@ -1,17 +1,14 @@ const placesReducer = ( - state = { places: [], ancestry_groups: [], loading: false }, + state = { places: [], ancestryGroups: [], loading: false }, action ) => { - console.log(`placesReducer called with action=${JSON.stringify(action)}`); switch (action.type) { case "LOADING_PLACES": return { ...state, - places: [...state.places], loading: true, }; case "ADD_PLACES": - console.log("hit ADD_PLACES in reducer"); return { ...state, places: action.places, @@ -26,16 +23,26 @@ const placesReducer = ( case "LOADING_ANCESTRY_GROUPS": return { ...state, - ancestry_groups: [...state.ancestry_groups], loading: true, }; case "ADD_ANCESTRY_GROUPS": console.log("hit ADD_ANCESTRY_GROUPS in reducer"); return { ...state, - ancestry_groups: action.ancestry_groups, + ancestryGroups: action.ancestryGroups, loading: false, }; + case "ADD_PLACE_ANCESTRY_GROUPS": + return { + ...state, + placeAncestryGroups: action.ancestryGroups.map((ancestryGroup) => { + return { + ancestryGroupId: ancestryGroup.id, + population: 0, + ancestryGroupName: ancestryGroup.attributes.name, + }; + }), + }; default: return state; }