-
-
- {user}
-
-
- {text}
-
-
-
-
+const Review = ({ id }) => {
+ /*
+id: "5909796d-5030-4e36-adec-68b8f9ec2d96"
+rating: 5
+text: "Not bad"
+userId: "a304959a-76c0-4b34-954a-b38dbf310360"
+ */
+
+ const reviews = useSelector((state) => state.reviews);
+ const users = useSelector((state) => state.users);
+ const review = reviews[id];
+ const { text, rating } = review;
+ const userId = review.userId;
+ const user = users[userId].name;
+
+ return (
+
+
+
+
+ {user}
+
+
+ {text}
+
+
+
+
+
-
-);
+ );
+};
Review.propTypes = {
user: PropTypes.string,
diff --git a/src/components/reviews/reviews.js b/src/components/reviews/reviews.js
index 0fdbf58..2a9ecae 100644
--- a/src/components/reviews/reviews.js
+++ b/src/components/reviews/reviews.js
@@ -1,15 +1,18 @@
-import React from 'react';
+import React, { useMemo } from 'react';
import PropTypes from 'prop-types';
import Review from './review';
import ReviewForm from './review-form';
import styles from './reviews.module.css';
+import { connect } from 'react-redux';
+import { allReviewsSelector } from '../../redux/selectors';
-const Reviews = ({ reviews }) => {
+const Reviews = ({ filteredReviews }) => {
return (
- {reviews.map((review) => (
-
+ {filteredReviews.map((review) => (
+
))}
+
);
diff --git a/src/redux/actions.js b/src/redux/actions.js
index 1403ee9..c2e2a68 100644
--- a/src/redux/actions.js
+++ b/src/redux/actions.js
@@ -1,5 +1,19 @@
-import { INCREMENT, DECREMENT, REMOVE } from './constants';
+import {
+ INCREMENT,
+ DECREMENT,
+ REMOVE,
+ POST_REVIEW,
+ SET_ACTIVE_RESTAURANT,
+} from './constants';
export const increment = (id) => ({ type: INCREMENT, payload: { id } });
export const decrement = (id) => ({ type: DECREMENT, payload: { id } });
export const remove = (id) => ({ type: REMOVE, payload: { id } });
+export const postReview = ({ yourName, text, rating }, activeRestaurantId) => ({
+ type: POST_REVIEW,
+ payload: { yourName, text, rating, activeRestaurantId },
+});
+export const setRestaurantActive = (id) => ({
+ type: SET_ACTIVE_RESTAURANT,
+ payload: { id },
+});
diff --git a/src/redux/constants.js b/src/redux/constants.js
index 9cfa25d..6b27785 100644
--- a/src/redux/constants.js
+++ b/src/redux/constants.js
@@ -1,3 +1,5 @@
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';
export const REMOVE = 'REMOVE';
+export const POST_REVIEW = 'POST_REVIEW';
+export const SET_ACTIVE_RESTAURANT = 'SET_ACTIVE_RESTAURANT';
diff --git a/src/redux/middleware/generateId.js b/src/redux/middleware/generateId.js
new file mode 100644
index 0000000..c702fda
--- /dev/null
+++ b/src/redux/middleware/generateId.js
@@ -0,0 +1,15 @@
+import { v4 as uuidv4 } from 'uuid';
+import restaurants from '../reducer/restaurants';
+
+export default (store) => (next) => (action) => {
+ if (action.type === 'POST_REVIEW') {
+ const newReviewId = uuidv4();
+ const newUserId = uuidv4();
+ action.payload.id = newReviewId;
+ action.payload.userId = newUserId;
+ //action.payload.restaurantId = store.getState().restaurants.activeRestaurantId
+ next(action);
+ } else {
+ next(action);
+ }
+};
diff --git a/src/redux/reducer/index.js b/src/redux/reducer/index.js
index f86f67d..3b5c632 100644
--- a/src/redux/reducer/index.js
+++ b/src/redux/reducer/index.js
@@ -3,10 +3,12 @@ import order from './order';
import restaurants from './restaurants';
import products from './products';
import reviews from './reviews';
+import users from './users';
export default combineReducers({
order,
restaurants,
products,
reviews,
+ users,
});
diff --git a/src/redux/reducer/products.js b/src/redux/reducer/products.js
index 6593f73..475b788 100644
--- a/src/redux/reducer/products.js
+++ b/src/redux/reducer/products.js
@@ -4,6 +4,7 @@ const defaultProducts = normalizedProducts.reduce(
(acc, product) => ({ ...acc, [product.id]: product }),
{}
);
+
export default (products = defaultProducts, action) => {
const { type } = action;
diff --git a/src/redux/reducer/restaurants.js b/src/redux/reducer/restaurants.js
index e7f30c6..c4d6a06 100644
--- a/src/redux/reducer/restaurants.js
+++ b/src/redux/reducer/restaurants.js
@@ -1,9 +1,34 @@
-import { normalizedRestaurants as defaultRestaurants } from '../../fixtures';
+import { normalizedRestaurants } from '../../fixtures';
+import { POST_REVIEW, SET_ACTIVE_RESTAURANT } from '../constants';
+
+const defaultRestaurants = normalizedRestaurants.reduce(
+ (acc, restaurant) => ({
+ ...acc,
+ [restaurant.id]: restaurant,
+ }),
+ {}
+);
export default (restaurants = defaultRestaurants, action) => {
- const { type } = action;
+ const { type, payload } = action;
switch (type) {
+ case SET_ACTIVE_RESTAURANT:
+ return { ...restaurants, activeRestaurantId: payload.id };
+ break;
+ case POST_REVIEW:
+ if (!payload.yourName) {
+ return { ...restaurants };
+ break;
+ }
+ const activeRestaurantId = payload.activeRestaurantId;
+ const restaurant = restaurants[activeRestaurantId];
+ restaurant.reviews.push(payload.id);
+ return {
+ ...restaurants,
+ [payload.activeRestaurantId]: restaurant,
+ };
+ break;
default:
return restaurants;
}
diff --git a/src/redux/reducer/reviews.js b/src/redux/reducer/reviews.js
index 494b5cd..8e08dff 100644
--- a/src/redux/reducer/reviews.js
+++ b/src/redux/reducer/reviews.js
@@ -1,9 +1,37 @@
-import { normalizedReviews as defaultReviews } from '../../fixtures';
+import { normalizedReviews } from '../../fixtures';
+import { POST_REVIEW } from '../constants';
+
+const defaultReviews = normalizedReviews.reduce(
+ (acc, review) => ({ ...acc, [review.id]: review }),
+ {}
+);
+defaultReviews.error = true;
export default (reviews = defaultReviews, action) => {
- const { type } = action;
+ const { type, payload } = action;
switch (type) {
+ case POST_REVIEW:
+ if (!payload.yourName) {
+ return {
+ ...reviews,
+ error: true,
+ errorMessage: 'name is required',
+ text: payload.text,
+ };
+ }
+ return {
+ ...reviews,
+ error: false,
+ errorMessage: '',
+ [payload.id]: {
+ id: payload.id,
+ rating: payload.rating,
+ text: payload.text,
+ userId: payload.userId,
+ },
+ };
+ break;
default:
return reviews;
}
diff --git a/src/redux/reducer/users.js b/src/redux/reducer/users.js
new file mode 100644
index 0000000..b9bd91b
--- /dev/null
+++ b/src/redux/reducer/users.js
@@ -0,0 +1,37 @@
+import { normalizedUsers } from '../../fixtures';
+import { POST_REVIEW } from '../constants';
+
+const defaultUsers = normalizedUsers.reduce(
+ (acc, user) => ({
+ ...acc,
+ [user.id]: user,
+ }),
+ {}
+);
+
+export default (users = defaultUsers, action) => {
+ const { type, payload } = action;
+
+ switch (type) {
+ case POST_REVIEW:
+ if (!payload.yourName) {
+ return { ...users };
+ break;
+ }
+ return {
+ ...users,
+ [payload.userId]: {
+ id: payload.userId,
+ name: payload.yourName,
+ },
+ };
+ default:
+ return users;
+ }
+};
+/*
+20bed9b5-9c7b-4771-8221-75b74ed1904a:
+id: "20bed9b5-9c7b-4771-8221-75b74ed1904a"
+name: "Diana"
+__proto__: Object
+ */
diff --git a/src/redux/selectors.js b/src/redux/selectors.js
index b4469a8..5dcd9a0 100644
--- a/src/redux/selectors.js
+++ b/src/redux/selectors.js
@@ -3,6 +3,9 @@ import { createSelector } from 'reselect';
// const restaurantsSelector = (state) => state.restaurants;
const orderSelector = (state) => state.order;
const productsSelector = (state) => state.products;
+const restaurantsSelector = (state) => state.restaurants;
+const reviewSelector = (state) => state.reviews;
+const usersSelector = (state) => state.users;
export const orderProductsSelector = createSelector(
productsSelector,
@@ -23,3 +26,47 @@ export const totalSelector = createSelector(
(orderProducts) =>
orderProducts.reduce((acc, { subtotal }) => acc + subtotal, 0)
);
+export const allRestaurantsSelector = createSelector(
+ restaurantsSelector,
+ (restaurants) =>
+ Object.keys(restaurants).map((restaurantId) => {
+ return restaurants[restaurantId];
+ })
+);
+//todo у меня есть объект с ревью я беру из него keys и
+// получаю массив ключей ревьюх, маплю их в объект
+//с user text rating и подключаю где нужно
+/*export const allReviewsSelector = createSelector(
+ usersSelector,
+ reviewSelector,
+
+ (users,reviews) =>
+ Object.keys(reviews).map((reviewId) => {
+ debugger
+ return {
+ user: users[reviews[reviewId].userId].name,
+ text: reviews[reviewId].text,
+ rating: reviews[reviewId].rating,
+ id: reviews[reviewId].id,
+ };
+ })
+);*/
+
+/*
+ {
+ id: '429dea85-11dd-4054-a31e-c60c92e17255',
+ userId: 'dfb982e9-b432-4b7d-aec6-7f6ff2e6af54',
+ text: 'No burgers',
+ rating: 3,
+ },
+ */
+
+/*
+ const Review = ({ user, text, rating, id }) => {
+ debugger
+ /*
+ id: "5db6247b-ab1c-49db-be1f-8dd27fd38b81"
+ rating: 5
+ text: "Finally! This place is amazing place for breakfast, lunch, dinner and supper"
+ userId: "dfb982e9-b432-4b7d-aec6-7f6ff2e6af54"
+ */
diff --git a/src/redux/store.js b/src/redux/store.js
index 602ccef..1a3f7ce 100644
--- a/src/redux/store.js
+++ b/src/redux/store.js
@@ -2,10 +2,11 @@ import { applyMiddleware, createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import reducer from './reducer';
import logger from './middleware/logger';
+import generateId from './middleware/generateId';
const store = createStore(
reducer,
- composeWithDevTools(applyMiddleware(logger))
+ composeWithDevTools(applyMiddleware(logger, generateId))
);
export default store;