| @@ -25,6 +25,8 @@ const CompanyChoser = forwardRef((props, ref) => { | |||
| setIsOpened(true); | |||
| } | |||
| }, [filters.companies.selectedCompaniesLocally]); | |||
| console.log("Comapnies", filters.companies) | |||
| return ( | |||
| <FilterSubDropdown | |||
| searchPlaceholder={t("filters.company.placeholder")} | |||
| @@ -7,14 +7,14 @@ const Checkbox = (props) => { | |||
| return ( | |||
| <CheckboxButton | |||
| leftText={props.companies ? item.company.name : item.city} | |||
| leftText={props.companies ? item.companyName : item.city} | |||
| // rightText={item.offerCount} | |||
| value={item} | |||
| checked={ | |||
| props.filters.find((itemInList) => | |||
| props.companies | |||
| ? itemInList?.company?.name?.toString() === | |||
| item?.company?.name?.toString() | |||
| ? itemInList?.companyName.toString() === | |||
| item?.companyName.toString() | |||
| : itemInList?.city?.toString() === item?.city?.toString() | |||
| ) | |||
| ? true | |||
| @@ -48,15 +48,15 @@ const CheckboxDropdownList = (props) => { | |||
| <SelectedItemsContainer> | |||
| {props.filters.map((item) => ( | |||
| <SelectedItem | |||
| key={props.companies ? item.company.name : item.city} | |||
| key={props.companies ? item?.companyName : item.city} | |||
| onClick={() => handleDelete(item)} | |||
| > | |||
| {props.companies | |||
| ? data.find( | |||
| (p) => | |||
| p?.company?.name?.toString() === | |||
| item?.company?.name?.toString() | |||
| )?.company?.name | |||
| p?.companyName?.toString() === | |||
| item?.companyName?.toString() | |||
| )?.companyName | |||
| : data.find( | |||
| (p) => p?.city?.toString() === item?.city?.toString() | |||
| )?.city} | |||
| @@ -19,7 +19,7 @@ const FilterCheckboxDropdown = (props) => { | |||
| setDataToShow( | |||
| data.filter((item) => | |||
| props.companies | |||
| ? item.company.name.toLowerCase().includes(toSearch.toLowerCase()) | |||
| ? item.companyName.toLowerCase().includes(toSearch.toLowerCase()) | |||
| : item.city.toLowerCase().includes(toSearch.toLowerCase()) | |||
| ) | |||
| ); | |||
| @@ -40,14 +40,13 @@ const FilterSmallDropdown = (props) => { | |||
| if ( | |||
| props.filters.find( | |||
| (itemInList) => | |||
| itemInList?.company?.name?.toString() === | |||
| item?.company?.name?.toString() | |||
| itemInList?.companyName?.toString() === | |||
| item?.companyName?.toString() | |||
| ) | |||
| ) { | |||
| props.setItemsSelected([ | |||
| ...props.filters.filter( | |||
| (p) => | |||
| p?.company?.name?.toString() !== item?.company?.name?.toString() | |||
| (p) => p?.companyName?.toString() !== item?.companyName?.toString() | |||
| ), | |||
| ]); | |||
| } else { | |||
| @@ -72,7 +71,7 @@ const FilterSmallDropdown = (props) => { | |||
| <SmallDropdownContent dropdown={showDropdown}> | |||
| {dataFiltered.map((item) => { | |||
| return ( | |||
| <DropdownItem key={item.company._id}> | |||
| <DropdownItem key={item._id}> | |||
| <Checkbox | |||
| item={item} | |||
| filters={props.filters} | |||
| @@ -20,7 +20,7 @@ const FilterSubDropdown = (props) => { | |||
| setDataToShow( | |||
| data.filter((item) => | |||
| props.companies | |||
| ? item.company.name.toLowerCase().includes(toSearch.toLowerCase()) | |||
| ? item.companyName.toLowerCase().includes(toSearch.toLowerCase()) | |||
| : item.city.toLowerCase().includes(toSearch.toLowerCase()) | |||
| ) | |||
| ); | |||
| @@ -24,6 +24,7 @@ import { ADMIN_SINGLE_USER_PAGE } from "../../../../constants/pages"; | |||
| const ProfileMainInfo = (props) => { | |||
| const { t } = useTranslation(); | |||
| const { isMobile } = useIsMobile(); | |||
| console.log(props.profile); | |||
| const goToUser = () => { | |||
| if (isAdminRoute()) { | |||
| history.push( | |||
| @@ -9,6 +9,7 @@ const UserReviewsCard = (props) => { | |||
| const handleRemove = () => { | |||
| setRemoveModalOpened(true); | |||
| }; | |||
| console.log(props); | |||
| const review = useMemo(() => { | |||
| if (props.givingReview) { | |||
| return { | |||
| @@ -33,24 +34,36 @@ const UserReviewsCard = (props) => { | |||
| ) | |||
| isGoodCommunication = reviewEnum.NO.mainText.toUpperCase(); | |||
| return { | |||
| name: props.review.userWhoGaveReview.name, | |||
| image: props.review.userWhoGaveReview.image, | |||
| _id: props.review._id, | |||
| name: | |||
| props.review?.reviewAdditionalData?.userWhoGave?.company?.name || | |||
| props.review?.offer?.name, | |||
| image: | |||
| props.review?.reviewAdditionalData?.userWhoGave?.image || | |||
| props.review?.offer?.image, | |||
| userId: props.review.userId, | |||
| isGoodCommunication, | |||
| isSuccessfulSwap, | |||
| quote: props?.review?.message, | |||
| offerName: props.review.offer.name, | |||
| offerImage: props.review.offer.image, | |||
| offerName: | |||
| props?.review?.reviewAdditionalData?.offerData?.name || | |||
| props?.review?.userWhoGaveReview?.name, | |||
| offerImage: | |||
| props?.review?.reviewAdditionalData?.offerData?.firstImage || | |||
| props?.review?.userWhoGaveReview?.image, | |||
| userWhoReceived: | |||
| props?.review?.reviewAdditionalData?.userWhoReceived?.company?.name, | |||
| }; | |||
| }, [props.review]); | |||
| console.log(review); | |||
| return ( | |||
| <> | |||
| <UserReviewsSingleCard | |||
| review={review} | |||
| showRemoveIcon={props.showRemoveIcon} | |||
| handleRemove={handleRemove} | |||
| hasGivenReview={props.hasGivenReview} | |||
| rightReviews={props.rightReviews} | |||
| /> | |||
| {removeModalOpened && ( | |||
| <DeleteReview | |||
| @@ -71,6 +84,8 @@ UserReviewsCard.propTypes = { | |||
| review: PropTypes.any, | |||
| givingReview: PropTypes.bool, | |||
| showRemoveIcon: PropTypes.bool, | |||
| hasGivenReview: PropTypes.bool, | |||
| rightReviews: PropTypes.bool, | |||
| }; | |||
| UserReviewsCard.defaultProps = { | |||
| isProfileReviews: false, | |||
| @@ -0,0 +1,25 @@ | |||
| import React from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { | |||
| GivenReviewsHeaderContainer, | |||
| CompanyName, | |||
| } from "./GivenReviewsHeader.styled"; | |||
| import { useTranslation } from "react-i18next"; | |||
| const GivenReviewsHeader = (props) => { | |||
| const { t } = useTranslation(); | |||
| console.log(props); | |||
| return ( | |||
| <GivenReviewsHeaderContainer hasGivenReview={props.hasGivenReview}> | |||
| {t("reviews.givenHeaderTitle")} | |||
| <CompanyName>{props.userWhoReceived}</CompanyName> | |||
| </GivenReviewsHeaderContainer> | |||
| ); | |||
| }; | |||
| GivenReviewsHeader.propTypes = { | |||
| hasGivenReview: PropTypes.bool, | |||
| userWhoReceived: PropTypes.any, | |||
| }; | |||
| export default GivenReviewsHeader; | |||
| @@ -0,0 +1,20 @@ | |||
| import styled from "styled-components"; | |||
| import { Box, Typography } from "@mui/material"; | |||
| import selectedTheme from "../../../../../themes"; | |||
| export const GivenReviewsHeaderContainer = styled(Box)` | |||
| display: ${(props) => (props.hasGivenReview ? "none" : "flex")}; | |||
| width: 100%; | |||
| background-color: #f5edff; | |||
| padding-top: 11px; | |||
| padding-left: 18px; | |||
| padding-bottom: 10px; | |||
| margin-bottom: 18px; | |||
| font-family: ${selectedTheme.fonts.textFont}; | |||
| border-radius: 4px; | |||
| `; | |||
| export const CompanyName = styled(Typography)` | |||
| color: ${selectedTheme.colors.primaryPurple}; | |||
| font-weight: 600; | |||
| `; | |||
| @@ -4,7 +4,10 @@ import { RemoveButtonContainer, RemoveIcon } from "./RemoveButton.styled"; | |||
| const RemoveButton = (props) => { | |||
| return ( | |||
| <RemoveButtonContainer onClick={props.onClick}> | |||
| <RemoveButtonContainer | |||
| onClick={props.onClick} | |||
| hasGivenReview={props.hasGivenReview} | |||
| > | |||
| <RemoveIcon /> | |||
| </RemoveButtonContainer> | |||
| ); | |||
| @@ -13,6 +16,7 @@ const RemoveButton = (props) => { | |||
| RemoveButton.propTypes = { | |||
| children: PropTypes.node, | |||
| onClick: PropTypes.func, | |||
| hasGivenReview: PropTypes.bool, | |||
| }; | |||
| export default RemoveButton; | |||
| @@ -6,7 +6,7 @@ import { IconButton } from "../../../../Buttons/IconButton/IconButton"; | |||
| export const RemoveButtonContainer = styled(IconButton)` | |||
| position: absolute; | |||
| top: 16px; | |||
| top: ${(props) => (!props.hasGivenReview ? "79px" : "16px")}; | |||
| right: 16px; | |||
| background-color: ${selectedTheme.colors.primaryIconBackgroundColor}; | |||
| border-radius: 100%; | |||
| @@ -17,5 +17,4 @@ export const RemoveButtonContainer = styled(IconButton)` | |||
| height: 32px; | |||
| } | |||
| `; | |||
| export const RemoveIcon = styled(Remove)` | |||
| `; | |||
| export const RemoveIcon = styled(Remove)``; | |||
| @@ -6,13 +6,21 @@ import ReviewQuote from "./ReviewQuote/ReviewQuote"; | |||
| import ReviewDetails from "./ReviewDetails/ReviewDetails"; | |||
| import RemoveButton from "./RemoveButton/RemoveButton"; | |||
| import ReviewOffer from "./ReviewOffer/ReviewOffer"; | |||
| import GivenReviewsHeader from "./GivenReviewsHeader/GivenReviewsHeader"; | |||
| const UserReviewsSingleCard = (props) => { | |||
| const handleRemove = () => { | |||
| props.handleRemove(); | |||
| }; | |||
| return ( | |||
| <ReviewContainer> | |||
| {!props.rightReviews && ( | |||
| <GivenReviewsHeader | |||
| hasGivenReview={props.hasGivenReview} | |||
| userWhoReceived={props.review?.userWhoReceived} | |||
| /> | |||
| )} | |||
| <ReviewerProfile | |||
| profileName={props.review?.name} | |||
| profileImage={props.review?.image} | |||
| @@ -27,7 +35,11 @@ const UserReviewsSingleCard = (props) => { | |||
| isGoodCommunication={props.review?.isGoodCommunication} | |||
| /> | |||
| {props.showRemoveIcon && ( | |||
| <RemoveButton review={props.review} onClick={handleRemove} /> | |||
| <RemoveButton | |||
| review={props.review} | |||
| onClick={handleRemove} | |||
| hasGivenReview={props.hasGivenReview} | |||
| /> | |||
| )} | |||
| <ReviewOffer | |||
| name={props.review?.offerName} | |||
| @@ -41,6 +53,9 @@ UserReviewsSingleCard.propTypes = { | |||
| review: PropTypes.any, | |||
| handleRemove: PropTypes.func, | |||
| showRemoveIcon: PropTypes.bool, | |||
| hasGivenReview: PropTypes.bool, | |||
| userWhoReceived: PropTypes.any, | |||
| rightReviews: PropTypes.bool, | |||
| }; | |||
| export default UserReviewsSingleCard; | |||
| @@ -4,6 +4,7 @@ import selectedTheme from "../../../../themes"; | |||
| export const ReviewContainer = styled(Box)` | |||
| padding-top: 18px; | |||
| padding-right: 12px; | |||
| position: relative; | |||
| @media (max-width: 600px) { | |||
| height: 258px; | |||
| @@ -18,4 +19,4 @@ export const ReviewContainer = styled(Box)` | |||
| left: -18px; | |||
| margin-top: 18px; | |||
| } | |||
| `; | |||
| `; | |||
| @@ -9,9 +9,22 @@ import BackdropComponent from "../../MUI/BackdropComponent"; | |||
| import UserReviewsSingleCard from "../../Cards/UserReviewsCard/UserReviewsSingleCard/UserReviewsSingleCard"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import DeleteButton from "./DeleteButton/DeleteButton"; | |||
| import { useDispatch } from "react-redux"; | |||
| import { removeReview } from "../../../store/actions/review/reviewActions"; | |||
| const DeleteReview = (props) => { | |||
| const dispatch = useDispatch(); | |||
| const reviewId = props.review._id; | |||
| const { t } = useTranslation(); | |||
| const handleApiResponseSuccess = () => { | |||
| console.log("Succes"); | |||
| }; | |||
| const deleteReviewHandler = () => { | |||
| dispatch(removeReview({ reviewId, handleApiResponseSuccess })); | |||
| props.setOpenedDeleteModal(false); | |||
| }; | |||
| return ( | |||
| <> | |||
| <BackdropComponent | |||
| @@ -27,7 +40,7 @@ const DeleteReview = (props) => { | |||
| review={props.review} | |||
| /> | |||
| <XIcon onClick={() => props.setOpenedDeleteModal(false)} /> | |||
| <DeleteButton /> | |||
| <DeleteButton onClick={deleteReviewHandler} /> | |||
| </DeleteReviewContainer> | |||
| </> | |||
| ); | |||
| @@ -17,9 +17,18 @@ const ReviewsSorting = forwardRef((props, ref) => { | |||
| const reviews = useSelector(selectSelectedReviews); | |||
| const dispatch = useDispatch(); | |||
| const [value, setValue] = useState(); | |||
| console.log(reviews); | |||
| const changeValue = (event) => { | |||
| if (props.isAdmin) { | |||
| console.log("sortiranje: ", event.target.value) | |||
| console.log("sortiranje: ", event.target.value); | |||
| // if(event.target.value.value === 1) { | |||
| // dispatch(setReviews(reviews.givenReviews)); | |||
| // } else { | |||
| // dispatch(setReviews(reviews.receivedReviews)); | |||
| // } | |||
| } else { | |||
| dispatch( | |||
| setReviews( | |||
| @@ -29,8 +38,8 @@ const ReviewsSorting = forwardRef((props, ref) => { | |||
| ) | |||
| ) | |||
| ); | |||
| props.changeSorting(); | |||
| } | |||
| props.changeSorting(event.target.value); | |||
| setValue(event.target.value); | |||
| }; | |||
| const sortEnum = useMemo(() => { | |||
| @@ -1,4 +1,4 @@ | |||
| import React, { useEffect, useMemo, useRef } from "react"; | |||
| import React, { useState, useEffect, useMemo, useRef } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { | |||
| ReviewList, | |||
| @@ -20,15 +20,21 @@ import { useRouteMatch } from "react-router-dom"; | |||
| import { | |||
| fetchReviews, | |||
| setReviews, | |||
| fetchReviewsAsAdmin, | |||
| } from "../../store/actions/review/reviewActions"; | |||
| import { selectIsLoadingByActionType } from "../../store/selectors/loadingSelectors"; | |||
| import SkeletonUserReviews from "./SkeletonUserReviews/SkeletonUserReviews"; | |||
| import { ONE_OFFER_SCOPE } from "../../store/actions/offers/offersActionConstants"; | |||
| import { REVIEW_GET_SCOPE } from "../../store/actions/review/reviewActionConstants"; | |||
| import { | |||
| REVIEW_GET_SCOPE, | |||
| REVIEW_GET_AS_ADMIN_SCOPE, | |||
| } from "../../store/actions/review/reviewActionConstants"; | |||
| import ReviewsSorting from "./ReviewsSorting/ReviewsSorting"; | |||
| import { sortReviews } from "../../util/helpers/reviewsHelper"; | |||
| // import { selectUserId } from "../../store/selectors/loginSelectors"; | |||
| const UserReviews = (props) => { | |||
| const [isGiven, setIsGiven] = useState(true); | |||
| const { t } = useTranslation(); | |||
| const offer = useSelector(selectOffer); | |||
| const reviews = useSelector(selectSelectedReviews); | |||
| @@ -36,25 +42,47 @@ const UserReviews = (props) => { | |||
| const dispatch = useDispatch(); | |||
| const listRef = useRef(null); | |||
| const sortRef = useRef(null); | |||
| // const userId = useSelector(selectUserId); | |||
| const isLoadingReview = useSelector( | |||
| selectIsLoadingByActionType( | |||
| props.isProfileReviews ? REVIEW_GET_SCOPE : ONE_OFFER_SCOPE | |||
| props.isAdmin | |||
| ? REVIEW_GET_AS_ADMIN_SCOPE | |||
| : props.isProfileReviews | |||
| ? REVIEW_GET_SCOPE | |||
| : ONE_OFFER_SCOPE | |||
| ) | |||
| ); | |||
| useEffect(() => { | |||
| if (props.profileReviews && routeMatch.params?.idProfile) { | |||
| let idProfile = routeMatch.params.idProfile; | |||
| dispatch(fetchReviews(idProfile)); | |||
| let idProfile = routeMatch.params.idProfile; | |||
| if (idProfile) { | |||
| if (props.isAdmin) { | |||
| dispatch(fetchReviewsAsAdmin(idProfile)); | |||
| } else { | |||
| dispatch(fetchReviews(idProfile)); | |||
| } | |||
| } | |||
| // if (props.profileReviews && routeMatch.params?.idProfile) { | |||
| // let idProfile = routeMatch.params.idProfile; | |||
| // dispatch(fetchReviews(idProfile)); | |||
| // } | |||
| }, [props.profileReviews, routeMatch]); | |||
| const lastThreeReviews = useMemo(() => { | |||
| if (props.givingReview) { | |||
| return [...props.profileReviews]; | |||
| console.log("isGiven", isGiven); | |||
| if (props.isAdmin) { | |||
| if (isGiven) { | |||
| return reviews.givenReviews; | |||
| } else { | |||
| return reviews.receivedReviews; | |||
| } | |||
| } | |||
| if (props.isProfileReviews) { | |||
| return [...reviews]; | |||
| return reviews; | |||
| } | |||
| if (props.givingReview) { | |||
| return [...props.profileReviews]; | |||
| } | |||
| if (offer?.companyData?.lastThreeReviews) { | |||
| // Making array of reviews in same order(sorting) so when comparing | |||
| @@ -68,13 +96,22 @@ const UserReviews = (props) => { | |||
| return [...reviews]; | |||
| } | |||
| return []; | |||
| }, [props.profileReviews, offer, props.isProfileReviews, reviews]); | |||
| }, [props.profileReviews, offer, props.isProfileReviews, reviews, isGiven]); | |||
| const scrollToTop = () => { | |||
| const handleChangeSorting = (newSortOption) => { | |||
| console.log(newSortOption); | |||
| listRef.current.scrollTo({ top: 0, behaviour: "smooth" }); | |||
| if (props.isAdmin) { | |||
| if (newSortOption.value === 1) { | |||
| setIsGiven(true); | |||
| } else { | |||
| setIsGiven(false); | |||
| } | |||
| } | |||
| }; | |||
| console.log(sortRef.current?.sortValue); | |||
| console.log(lastThreeReviews); | |||
| return ( | |||
| <UserReviewsContainer className={props.className}> | |||
| {!props.givingReview && | |||
| @@ -102,7 +139,7 @@ const UserReviews = (props) => { | |||
| <ReviewsTitle>{t("reviews.rates")}</ReviewsTitle> | |||
| </ReviewsHeaderTitle> | |||
| <ReviewsSorting | |||
| changeSorting={scrollToTop} | |||
| changeSorting={handleChangeSorting} | |||
| ref={sortRef} | |||
| isAdmin={props.isAdmin} | |||
| /> | |||
| @@ -117,6 +154,7 @@ const UserReviews = (props) => { | |||
| key={index} | |||
| hasGivenReview={sortRef.current?.hasGivenReview} | |||
| givingReview={props.givingReview} | |||
| rightReviews={props.rightReviews} | |||
| /> | |||
| )) | |||
| ) : ( | |||
| @@ -138,6 +176,7 @@ UserReviews.propTypes = { | |||
| givingReview: PropTypes.bool, | |||
| offer: PropTypes.any, | |||
| isAdmin: PropTypes.bool, | |||
| rightReviews: PropTypes.bool, | |||
| }; | |||
| UserReviews.defaultProps = { | |||
| isProfileReviews: false, | |||
| @@ -5,9 +5,10 @@ export const KEY_SUBCATEGORY = "subcategory"; | |||
| export const KEY_SORTBY = "sortBy"; | |||
| export const KEY_SORT_DATE = "_des_date"; | |||
| export const KEY_SORT_POPULAR = "_des_popular"; | |||
| export const KEY_LOCATION = "location" | |||
| export const KEY_LOCATION = "location"; | |||
| export const KEY_COMPANY = "companyName"; | |||
| export const KEY_NAME = "name"; | |||
| export const KEY_SEARCH = "search" | |||
| export const KEY_SEARCH = "search"; | |||
| export const VALUE_SORTBY_NEW = "newest"; | |||
| export const VALUE_SORTBY_OLD = "oldest"; | |||
| export const VALUE_SORTBY_POPULAR = "popular"; | |||
| @@ -14,9 +14,14 @@ const useCompaniesFilter = () => { | |||
| dispatch(fetchAllProfiles()); | |||
| }, []); | |||
| const selectedCompanies = useMemo(() => Array.isArray(selectedCompaniesRedux) ? selectedCompaniesRedux : []) | |||
| const allCompanies = useMemo(() => Array.isArray(allCompaniesRedux) ? selectedCompaniesRedux : []) | |||
| const selectedCompanies = useMemo(() => | |||
| Array.isArray(selectedCompaniesRedux) ? selectedCompaniesRedux : [] | |||
| ); | |||
| console.log('allcompanies', allCompaniesRedux); | |||
| const allCompanies = useMemo(() => | |||
| Array.isArray(allCompaniesRedux) ? allCompaniesRedux : [] | |||
| ); | |||
| useEffect(() => { | |||
| setSelectedCompaniesLocally(selectedCompanies); | |||
| @@ -33,7 +38,7 @@ const useCompaniesFilter = () => { | |||
| let companiesToPush = []; | |||
| companies.forEach((companyName) => { | |||
| companiesToPush.push( | |||
| allCompanies.find((p) => p.company.name === companyName) | |||
| allCompanies.find((p) => p.companyName === companyName) | |||
| ); | |||
| }); | |||
| setSelectedCompanies([...companiesToPush]); | |||
| @@ -3,6 +3,7 @@ import { useDispatch, useSelector } from "react-redux"; | |||
| import { | |||
| KEY_CATEGORY, | |||
| KEY_LOCATION, | |||
| KEY_COMPANY, | |||
| KEY_PAGE, | |||
| KEY_SEARCH, | |||
| KEY_SORTBY, | |||
| @@ -89,6 +90,11 @@ const useOffers = () => { | |||
| queryObject[KEY_LOCATION] | |||
| ); | |||
| } | |||
| if (KEY_COMPANY in queryObject) { | |||
| filters.companies.setSelectedCompaniesFromArray( | |||
| queryObject[KEY_COMPANY] | |||
| ); | |||
| } | |||
| if (KEY_SORTBY in queryObject) { | |||
| sorting.changeSortingFromName(queryObject[KEY_SORTBY]); | |||
| } | |||
| @@ -227,7 +227,8 @@ export default { | |||
| finishedReviewTitle: "Hvala vam", | |||
| finishedReviewAltTitle: "na izdvojenom vremenu i datoj oceni!", | |||
| sortBy: "Sortiraj po", | |||
| offerTitle: "Proizvod:" | |||
| offerTitle: "Proizvod:", | |||
| givenHeaderTitle: "Ocenjena kompanija: ", | |||
| }, | |||
| messages: { | |||
| headerTitle: "Moje Ćaskanje", | |||
| @@ -29,7 +29,7 @@ const AdminUsersPage = () => { | |||
| const allUsers = useSelector(selectAllProfiles); | |||
| const totalUsers = useSelector(selectTotalProfiles); | |||
| const allUsersToShow = useMemo( | |||
| () => (Array.isArray(allUsers) ? allUsers : []), | |||
| () => (Array.isArray(allUsers?.users) ? allUsers?.users : []), | |||
| [allUsers] | |||
| ); | |||
| useEffect(() => { | |||
| @@ -39,7 +39,7 @@ const ItemDetailsPage = (props) => { | |||
| content={<ItemDetails singleOffer />} | |||
| rightCard={ | |||
| <> | |||
| <ProfileMini /> <UserReviews /> | |||
| <ProfileMini /> <UserReviews rightReviews /> | |||
| </> | |||
| } | |||
| /> | |||
| @@ -119,9 +119,9 @@ export default { | |||
| updateUserRegistration: "/users/{userUid}", | |||
| invite: "/users/invite", | |||
| getProfile: "users/", | |||
| editProfile: "users", | |||
| editProfile: "users/{userId}", | |||
| getAllProfiles: "users/companies", | |||
| editProfileAsAdmin: "admin/users/{userId}", | |||
| getAllProfiles: "users", | |||
| getAllProfilesAsAdmin: "admin/users", | |||
| deleteProfileAsAdmin: "admin/users/{userId}", | |||
| blockProfileAsAdmin: "admin/users/{userId}/block", | |||
| @@ -188,7 +188,9 @@ export default { | |||
| validateExchange: "exchanges", | |||
| }, | |||
| reviews: { | |||
| postReview: "reviews", | |||
| getUserReviews: "/users/{userId}/reviews", | |||
| postReview: "/users/{userId}/reviews", | |||
| removeReview: "/admin/reviews/{id}", | |||
| }, | |||
| admin: { | |||
| categories: { | |||
| @@ -204,7 +206,10 @@ export default { | |||
| locations: { | |||
| newLocation: "admin/locations", | |||
| editLocation: "admin/locations/{locationId}", | |||
| deleteLocation: "admin/locations/{locationId}" | |||
| deleteLocation: "admin/locations/{locationId}", | |||
| }, | |||
| reviews: { | |||
| getUserReviewsAsAdmin: 'admin/reviews/{userId}' | |||
| } | |||
| }, | |||
| }; | |||
| @@ -15,8 +15,12 @@ export const attemptFetchAllProfiles = () => | |||
| export const attemptFetchAllProfilesAsAdmin = (payload) => | |||
| getRequest(apiEndpoints.users.getAllProfilesAsAdmin + "?" + payload); | |||
| export const attemptEditProfile = (payload, requestData) => | |||
| putRequest(apiEndpoints.users.editProfile + "/" + payload, requestData); | |||
| export const attemptEditProfile = (payload, requestData) => { | |||
| return putRequest( | |||
| replaceInUrl(apiEndpoints.users.editProfile, { userId: payload }), | |||
| requestData | |||
| ); | |||
| }; | |||
| export const attemptEditProfileAsAdmin = (payload, requestData) => | |||
| putRequest( | |||
| replaceInUrl(apiEndpoints.users.editProfileAsAdmin, { userId: payload }), | |||
| @@ -1,9 +1,24 @@ | |||
| import { getRequest, postRequest } from "." | |||
| import apiEndpoints from "./apiEndpoints" | |||
| import { deleteRequest, getRequest, postRequest, replaceInUrl } from "."; | |||
| import apiEndpoints from "./apiEndpoints"; | |||
| export const attemptGiveReview = (payload) => { | |||
| return postRequest(apiEndpoints.reviews.postReview, payload); | |||
| } | |||
| export const attemptGiveReview = (userId, payload) => { | |||
| return postRequest( | |||
| replaceInUrl(apiEndpoints.reviews.postReview, { userId: userId }), | |||
| payload | |||
| ); | |||
| }; | |||
| export const attemptFetchReview = (payload) => { | |||
| return getRequest(`users/${payload}/reviews`) | |||
| } | |||
| return getRequest( | |||
| replaceInUrl(apiEndpoints.reviews.getUserReviews, { userId: payload }) | |||
| ); | |||
| }; | |||
| export const attemptRemoveReview = (payload) => { | |||
| return deleteRequest( | |||
| replaceInUrl(apiEndpoints.reviews.removeReview, { id: payload }) | |||
| ); | |||
| }; | |||
| export const attemptFetchReviewsAsAdmin = (payload) => { | |||
| return getRequest( | |||
| replaceInUrl(apiEndpoints.admin.reviews.getUserReviewsAsAdmin, {userId: payload}) | |||
| ); | |||
| }; | |||
| @@ -15,4 +15,14 @@ export const REVIEW_GET = createFetchType(REVIEW_GET_SCOPE); | |||
| export const REVIEW_GET_SUCCESS = createSuccessType(REVIEW_GET_SCOPE); | |||
| export const REVIEW_GET_ERROR = createErrorType(REVIEW_GET_SCOPE); | |||
| export const REVIEW_REMOVE_SCOPE = "REVIEW_REMOVE_SCOPE"; | |||
| export const REVIEW_REMOVE = createFetchType(REVIEW_REMOVE_SCOPE); | |||
| export const REVIEW_REMOVE_SUCCESS = createSuccessType(REVIEW_REMOVE_SCOPE); | |||
| export const REVIEW_REMOVE_ERROR = createErrorType(REVIEW_REMOVE_SCOPE); | |||
| export const REVIEW_GET_AS_ADMIN_SCOPE = 'REVIEW_GET_AS_ADMIN_SCOPE'; | |||
| export const REVIEW_GET_AS_ADMIN = createFetchType(REVIEW_GET_AS_ADMIN_SCOPE); | |||
| export const REVIEW_GET_AS_ADMIN_SUCCESS = createSuccessType(REVIEW_GET_AS_ADMIN_SCOPE); | |||
| export const REVIEW_GET_AS_ADMIN_ERROR = createErrorType(REVIEW_GET_AS_ADMIN_SCOPE); | |||
| export const REVIEW_SET = createSetType("REVIEW_SET"); | |||
| @@ -1,26 +1,61 @@ | |||
| import { REVIEW_GET, REVIEW_GET_ERROR, REVIEW_GET_SUCCESS, REVIEW_GIVE, REVIEW_GIVE_ERROR, REVIEW_GIVE_SUCCESS, REVIEW_SET } from "./reviewActionConstants"; | |||
| import { | |||
| REVIEW_GET, | |||
| REVIEW_GET_ERROR, | |||
| REVIEW_GET_SUCCESS, | |||
| REVIEW_GIVE, | |||
| REVIEW_GIVE_ERROR, | |||
| REVIEW_GIVE_SUCCESS, | |||
| REVIEW_REMOVE, | |||
| REVIEW_REMOVE_ERROR, | |||
| REVIEW_REMOVE_SUCCESS, | |||
| REVIEW_GET_AS_ADMIN, | |||
| REVIEW_GET_AS_ADMIN_SUCCESS, | |||
| REVIEW_GET_AS_ADMIN_ERROR, | |||
| REVIEW_SET, | |||
| } from "./reviewActionConstants"; | |||
| export const fetchReviews = (payload) => ({ | |||
| type: REVIEW_GET, | |||
| payload, | |||
| }) | |||
| type: REVIEW_GET, | |||
| payload, | |||
| }); | |||
| export const fetchReviewsSuccess = () => ({ | |||
| type: REVIEW_GET_SUCCESS | |||
| }) | |||
| type: REVIEW_GET_SUCCESS, | |||
| }); | |||
| export const fetchReviewsError = () => ({ | |||
| type: REVIEW_GET_ERROR | |||
| }) | |||
| type: REVIEW_GET_ERROR, | |||
| }); | |||
| export const giveReview = (payload) => ({ | |||
| type: REVIEW_GIVE, | |||
| payload, | |||
| }) | |||
| type: REVIEW_GIVE, | |||
| payload, | |||
| }); | |||
| export const giveReviewSuccess = () => ({ | |||
| type: REVIEW_GIVE_SUCCESS | |||
| }) | |||
| type: REVIEW_GIVE_SUCCESS, | |||
| }); | |||
| export const giveReviewError = () => ({ | |||
| type: REVIEW_GIVE_ERROR | |||
| type: REVIEW_GIVE_ERROR, | |||
| }); | |||
| export const removeReview = (payload) => ({ | |||
| type: REVIEW_REMOVE, | |||
| payload, | |||
| }); | |||
| export const removeReviewSuccess = () => ({ | |||
| type: REVIEW_REMOVE_SUCCESS, | |||
| }); | |||
| export const removeReviewError = () => ({ | |||
| type: REVIEW_REMOVE_ERROR, | |||
| }); | |||
| export const fetchReviewsAsAdmin = (payload) => ({ | |||
| type: REVIEW_GET_AS_ADMIN, | |||
| payload, | |||
| }); | |||
| export const fetchReviewsAsAdminSuccess = () => ({ | |||
| type: REVIEW_GET_AS_ADMIN_SUCCESS, | |||
| }); | |||
| export const fetchReviewsAsAdminError = () => ({ | |||
| type: REVIEW_GET_AS_ADMIN_ERROR | |||
| }) | |||
| export const setReviews = (payload) => ({ | |||
| type: REVIEW_SET, | |||
| payload, | |||
| }) | |||
| type: REVIEW_SET, | |||
| payload, | |||
| }); | |||
| @@ -1,22 +1,32 @@ | |||
| import { all, takeLatest, call, put } from "@redux-saga/core/effects"; | |||
| import { all, takeLatest, call, put, select } from "@redux-saga/core/effects"; | |||
| import { | |||
| attemptFetchReview, | |||
| attemptGiveReview, | |||
| attemptRemoveReview, | |||
| attemptFetchReviewsAsAdmin, | |||
| } from "../../request/reviewRequest"; | |||
| import { | |||
| REVIEW_GET, | |||
| REVIEW_GIVE, | |||
| REVIEW_REMOVE, | |||
| REVIEW_GET_AS_ADMIN, | |||
| } from "../actions/review/reviewActionConstants"; | |||
| import { | |||
| fetchReviewsError, | |||
| fetchReviewsSuccess, | |||
| giveReviewError, | |||
| giveReviewSuccess, | |||
| removeReviewError, | |||
| removeReviewSuccess, | |||
| fetchReviewsAsAdminSuccess, | |||
| fetchReviewsAsAdminError, | |||
| setReviews, | |||
| } from "../actions/review/reviewActions"; | |||
| import { selectUserId } from "../selectors/loginSelectors"; | |||
| function* fetchReviews(payload) { | |||
| try { | |||
| console.log(payload); | |||
| const data = yield call(attemptFetchReview, payload.payload); | |||
| yield put(setReviews([...data.data].reverse())); | |||
| yield put(fetchReviewsSuccess()); | |||
| @@ -28,7 +38,8 @@ function* fetchReviews(payload) { | |||
| function* giveReview(payload) { | |||
| try { | |||
| yield call(attemptGiveReview, payload.payload.review); | |||
| const userId = yield select(selectUserId); | |||
| yield call(attemptGiveReview, userId, payload.payload.review); | |||
| if (payload.payload.handleApiResponseSuccess) { | |||
| yield call(payload.payload.handleApiResponseSuccess); | |||
| } | |||
| @@ -39,9 +50,41 @@ function* giveReview(payload) { | |||
| } | |||
| } | |||
| function* removeReview(payload) { | |||
| try { | |||
| console.log(payload); | |||
| yield call(attemptRemoveReview, payload.payload.reviewId); | |||
| if (payload.payload.handleApiResponseSuccess) { | |||
| yield call(payload.payload.handleApiResponseSuccess); | |||
| } | |||
| yield put(removeReviewSuccess()); | |||
| } catch (e) { | |||
| yield put(removeReviewError()); | |||
| console.dir(e); | |||
| } | |||
| } | |||
| function* fetchReviewsAsAdmin(payload) { | |||
| try { | |||
| console.log(payload); | |||
| const data = yield call(attemptFetchReviewsAsAdmin, payload.payload); | |||
| if (payload.payload.handleApiResponseSuccess) { | |||
| yield call(payload.payload.handleApiResponseSuccess); | |||
| } | |||
| console.log(data); | |||
| yield put(setReviews(data.data)); | |||
| yield put(fetchReviewsAsAdminSuccess()); | |||
| } catch (e) { | |||
| yield put(fetchReviewsAsAdminError()); | |||
| console.dir(e); | |||
| } | |||
| } | |||
| export default function* reviewSaga() { | |||
| yield all([ | |||
| takeLatest(REVIEW_GET, fetchReviews), | |||
| takeLatest(REVIEW_GIVE, giveReview), | |||
| takeLatest(REVIEW_REMOVE, removeReview), | |||
| takeLatest(REVIEW_GET_AS_ADMIN, fetchReviewsAsAdmin), | |||
| ]); | |||
| } | |||
| @@ -20,7 +20,7 @@ export const selectMineProfilePicture = createSelector( | |||
| ); | |||
| export const selectAllProfiles = createSelector( | |||
| profileSelector, | |||
| (state) => state.allProfiles?.users | |||
| (state) => state?.allProfiles | |||
| ); | |||
| export const selectTotalProfiles = createSelector( | |||
| profileSelector, | |||
| @@ -1,5 +1,5 @@ | |||
| export const filterCompanies = (data, regexp) => { | |||
| return data.filter((company) => { | |||
| return regexp.test(company?.company?.name); | |||
| return regexp.test(company?.companyName); | |||
| }); | |||
| }; | |||
| @@ -6,6 +6,7 @@ import { | |||
| import { | |||
| initialSize, | |||
| KEY_CATEGORY, | |||
| KEY_COMPANY, | |||
| KEY_LOCATION, | |||
| KEY_NAME, | |||
| KEY_PAGE, | |||
| @@ -117,6 +118,13 @@ export const convertQueryStringForBackend = (queryURL) => { | |||
| newQueryObject.append(KEY_LOCATION, item); | |||
| }); | |||
| } | |||
| if (queryObject.has(KEY_COMPANY)) { | |||
| const arrayOfCompanies = queryObject.getAll(KEY_COMPANY); | |||
| arrayOfCompanies.forEach((item) => { | |||
| console.log(item); | |||
| newQueryObject.append(KEY_COMPANY, item); | |||
| }); | |||
| } | |||
| if (queryObject.has(KEY_SORTBY)) { | |||
| newQueryObject.delete(KEY_SORTBY); | |||
| if (queryObject.get(KEY_SORTBY) === VALUE_SORTBY_NEW) { | |||
| @@ -166,6 +174,13 @@ export const getQueryObjectHelper = (queryString) => { | |||
| newObject[KEY_LOCATION].push(item); | |||
| }); | |||
| } | |||
| if (queryObject.has(KEY_COMPANY)) { | |||
| const arrayOfCompanies = queryObject.getAll(KEY_COMPANY); | |||
| newObject[KEY_COMPANY] = []; | |||
| arrayOfCompanies.forEach((item) => { | |||
| newObject[KEY_COMPANY].push(item); | |||
| }); | |||
| } | |||
| if (queryObject.has(KEY_SORTBY)) { | |||
| newObject[KEY_SORTBY] = queryObject.get(KEY_SORTBY); | |||
| } | |||
| @@ -188,6 +203,7 @@ export const makeHeaderStringHelper = (filters) => { | |||
| let categoryString = `${ALL_CATEGORIES}`; | |||
| let subcategoryString = ""; | |||
| let locationsString = ""; | |||
| let companiesString = ""; | |||
| // Adding category to header string | |||
| if (filters?.category?.selectedCategory?.name) { | |||
| categoryString = filters.category.selectedCategory?.name; | |||
| @@ -212,11 +228,29 @@ export const makeHeaderStringHelper = (filters) => { | |||
| } | |||
| }); | |||
| } | |||
| let headerStringLocal = categoryString + subcategoryString + locationsString; | |||
| if ( | |||
| filters?.companies?.selectedCompanies && | |||
| filters?.companies?.selectedCompanies?.length > 0 | |||
| ) { | |||
| companiesString = SPREAD; | |||
| filters.companies.selectedCompanies.forEach((company, index) => { | |||
| // Checking if item is last | |||
| console.log(company); | |||
| if (index + 1 === filters.companies.selectedCompanies.length) { | |||
| companiesString += company.companyName; | |||
| } else { | |||
| companiesString += company.companyName + COMMA; | |||
| } | |||
| }); | |||
| } | |||
| let headerStringLocal = | |||
| categoryString + subcategoryString + locationsString + companiesString; | |||
| return { | |||
| categoryString, | |||
| subcategoryString, | |||
| locationsString, | |||
| companiesString, | |||
| text: headerStringLocal, | |||
| }; | |||
| }; | |||
| @@ -225,6 +259,7 @@ export const makeHeaderStringFromQueryObjectHelper = (queryObject) => { | |||
| let categoryString = `${ALL_CATEGORIES}`; | |||
| let subcategoryString = ""; | |||
| let locationsString = ""; | |||
| let companiesString = ""; | |||
| if (KEY_CATEGORY in queryObject) { | |||
| categoryString = queryObject[KEY_CATEGORY]; | |||
| if (KEY_SUBCATEGORY in queryObject) { | |||
| @@ -246,12 +281,29 @@ export const makeHeaderStringFromQueryObjectHelper = (queryObject) => { | |||
| }); | |||
| } | |||
| } | |||
| let headerStringLocal = categoryString + subcategoryString + locationsString; | |||
| if (KEY_COMPANY in queryObject) { | |||
| companiesString = SPREAD; | |||
| if (!Array.isArray(queryObject[KEY_COMPANY])) { | |||
| companiesString += queryObject[KEY_COMPANY]; | |||
| } else { | |||
| queryObject[KEY_COMPANY].forEach((company, index) => { | |||
| // Checking if item is last | |||
| if (index + 1 === queryObject[KEY_COMPANY].length) { | |||
| companiesString += company; | |||
| } else { | |||
| companiesString += company + COMMA; | |||
| } | |||
| }); | |||
| } | |||
| } | |||
| let headerStringLocal = | |||
| categoryString + subcategoryString + locationsString + companiesString; | |||
| return { | |||
| categoryString, | |||
| subcategoryString, | |||
| locationsString, | |||
| companiesString, | |||
| text: headerStringLocal, | |||
| }; | |||
| }; | |||
| @@ -274,6 +326,11 @@ export const makeQueryStringHelper = (filters, paging, search, sorting) => { | |||
| newQueryString.append(KEY_LOCATION, location?.city) | |||
| ); | |||
| } | |||
| if (filters.companies.selectedCompaniesLocally?.length > 0) { | |||
| filters.companies.selectedCompaniesLocally.forEach((company) => | |||
| newQueryString.append(KEY_COMPANY, company?.companyName) | |||
| ); | |||
| } | |||
| if (sorting.selectedSortOption?.value) { | |||
| if (sorting.selectedSortOption?.value === sortEnum.NEW.value) { | |||
| newQueryString.append(KEY_SORTBY, VALUE_SORTBY_NEW); | |||
| @@ -4,7 +4,7 @@ export default (locations) => | |||
| Yup.object().shape({ | |||
| firmName: Yup.string().required(i18n.t("editProfile.labelNameRequired")), | |||
| firmPIB: Yup.string() | |||
| .required(i18n.t("editProfile.labelPIBRequired")) | |||
| // .required(i18n.t("editProfile.labelPIBRequired")) | |||
| .min(9, i18n.t("register.PIBnoOfCharacters")) | |||
| .max(9, i18n.t("register.PIBnoOfCharacters")), | |||
| firmLocation: Yup.string().oneOf( | |||