| flex: 1 0 auto; | flex: 1 0 auto; | ||||
| } | } | ||||
| #root { | |||||
| margin-top: 80px; | |||||
| } | |||||
| input[type='search']::-webkit-search-decoration, | input[type='search']::-webkit-search-decoration, | ||||
| input[type='search']::-webkit-search-cancel-button, | input[type='search']::-webkit-search-cancel-button, | ||||
| input[type='search']::-webkit-search-results-button, | input[type='search']::-webkit-search-results-button, |
| import { NavLink } from "react-router-dom"; | import { NavLink } from "react-router-dom"; | ||||
| import * as Yup from "yup"; | import * as Yup from "yup"; | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import { fetchUser } from "../../../store/actions/login/loginActions"; | |||||
| import { fetchLogin } from "../../../store/actions/login/loginActions"; | |||||
| import { FORGOT_PASSWORD_PAGE, HOME_PAGE } from "../../../constants/pages"; | import { FORGOT_PASSWORD_PAGE, HOME_PAGE } from "../../../constants/pages"; | ||||
| import { ReactComponent as VisibilityOn } from "../../../assets/images/svg/eye-striked.svg"; | import { ReactComponent as VisibilityOn } from "../../../assets/images/svg/eye-striked.svg"; | ||||
| import { ReactComponent as VisibilityOff } from "../../../assets/images/svg/eye.svg"; | import { ReactComponent as VisibilityOff } from "../../../assets/images/svg/eye.svg"; | ||||
| const handleSubmit = (values) => { | const handleSubmit = (values) => { | ||||
| const { username: email, password: password } = values; | const { username: email, password: password } = values; | ||||
| dispatch( | dispatch( | ||||
| fetchUser({ | |||||
| fetchLogin({ | |||||
| email, | email, | ||||
| password, | password, | ||||
| handleApiResponseSuccess, | handleApiResponseSuccess, |
| const FirstPartCreateOffer = (props) => { | const FirstPartCreateOffer = (props) => { | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| const handleSubmit = (values) => { | const handleSubmit = (values) => { | ||||
| console.log(values); | |||||
| props.handleNext(values); | props.handleNext(values); | ||||
| }; | }; | ||||
| const formik = useFormik({ | const formik = useFormik({ |
| const SecondPartCreateOffer = () => { | const SecondPartCreateOffer = () => { | ||||
| const [images, setImages] = useState([null, null, null]); // 3 images | const [images, setImages] = useState([null, null, null]); // 3 images | ||||
| const setImage = (index, image) => { | const setImage = (index, image) => { | ||||
| console.log(images); | |||||
| setImages((prevState) => { | setImages((prevState) => { | ||||
| let newState = [...prevState]; | let newState = [...prevState]; | ||||
| newState[index] = image; | newState[index] = image; |
| </DropdownItem> | </DropdownItem> | ||||
| )} | )} | ||||
| {dataToShow.map((item) => { | {dataToShow.map((item) => { | ||||
| {/* console.log("item: ", item); */} | |||||
| return ( | return ( | ||||
| <DropdownItem | <DropdownItem | ||||
| key={item.name} | key={item.name} |
| import { Icon } from "../Icon/Icon"; | import { Icon } from "../Icon/Icon"; | ||||
| import { useSelector } from "react-redux"; | import { useSelector } from "react-redux"; | ||||
| import { selectJWTToken } from "../../store/selectors/loginSelectors"; | import { selectJWTToken } from "../../store/selectors/loginSelectors"; | ||||
| import { useSearch } from "../../hooks/useSearch"; | |||||
| import { selectProfileName } from "../../store/selectors/profileSelectors"; | |||||
| const Header = () => { | const Header = () => { | ||||
| const [openDrawer, setOpenDrawer] = useState(false); | const [openDrawer, setOpenDrawer] = useState(false); | ||||
| const searchRef = useRef(null); | const searchRef = useRef(null); | ||||
| const matches = useMediaQuery(theme.breakpoints.down("md")); | const matches = useMediaQuery(theme.breakpoints.down("md")); | ||||
| const user = useSelector(selectJWTToken); | const user = useSelector(selectJWTToken); | ||||
| const search = useSearch(); | |||||
| const name = useSelector(selectProfileName); | |||||
| const handleToggleDrawer = () => { | const handleToggleDrawer = () => { | ||||
| setOpenDrawer(!openDrawer); | setOpenDrawer(!openDrawer); | ||||
| }; | }; | ||||
| const [postsPopoverOpen, setPostsPopoverOpen] = useState(false); | const [postsPopoverOpen, setPostsPopoverOpen] = useState(false); | ||||
| const [postsAnchorEl, setPostsAnchorEl] = useState(null); | const [postsAnchorEl, setPostsAnchorEl] = useState(null); | ||||
| ) { | ) { | ||||
| shouldShowHeader = false; | shouldShowHeader = false; | ||||
| } | } | ||||
| console.log(user); | |||||
| if (location.pathname === "/" && user.JwtToken?.length === 0) { | if (location.pathname === "/" && user.JwtToken?.length === 0) { | ||||
| shouldShowHeader = false; | shouldShowHeader = false; | ||||
| } | } | ||||
| setShouldShow(shouldShowHeader); | setShouldShow(shouldShowHeader); | ||||
| }, [location, user]); | }, [location, user]); | ||||
| // let listener; | |||||
| let listener; | |||||
| const handleFocusSearch = () => { | const handleFocusSearch = () => { | ||||
| // console.log('focus'); | |||||
| // listener = (event) => { | |||||
| // if (event.keyCode === 13) { | |||||
| // event.preventDefault(); | |||||
| // console.log('detektovano'); | |||||
| // } | |||||
| // } | |||||
| // searchRef.current.addEventListener('keyup', listener); | |||||
| } | |||||
| listener = (event) => { | |||||
| if (event.keyCode === 13) { | |||||
| event.preventDefault(); | |||||
| search.searchOffers(searchRef.current.value) | |||||
| } | |||||
| } | |||||
| searchRef.current.addEventListener('keyup', listener); | |||||
| }; | |||||
| const handleBlurSearch = () => { | const handleBlurSearch = () => { | ||||
| // console.log('blur'); | |||||
| // searchRef.current.removeEventListener('keyup', listener); | |||||
| } | |||||
| searchRef.current.removeEventListener('keyup', listener); | |||||
| }; | |||||
| const drawerContent = useMemo( | const drawerContent = useMemo( | ||||
| () => ( | () => ( | ||||
| return ( | return ( | ||||
| <AppBar | <AppBar | ||||
| elevation={0} | elevation={0} | ||||
| positionFixed | |||||
| sx={{ backgroundColor: "white"}} | |||||
| style={{display: shouldShow ? "flex" : "none"}} | |||||
| position="fixed" | |||||
| // positionFixed | |||||
| sx={{ backgroundColor: "white" }} | |||||
| style={{ display: shouldShow ? "flex" : "none" }} | |||||
| > | > | ||||
| <Toolbar> | <Toolbar> | ||||
| <ToolsContainer> | <ToolsContainer> | ||||
| <MailIcon /> | <MailIcon /> | ||||
| </Badge> | </Badge> | ||||
| </IconButton> | </IconButton> | ||||
| <UserButton onClick={(e) => { | |||||
| setUserPopoverOpen(true); | |||||
| setUserAnchorEl(e.currentTarget); | |||||
| }}> | |||||
| <UserName> | |||||
| Username korisnika | |||||
| </UserName> | |||||
| <UserButton | |||||
| onClick={(e) => { | |||||
| setUserPopoverOpen(true); | |||||
| setUserAnchorEl(e.currentTarget); | |||||
| }} | |||||
| > | |||||
| <UserName>{name}</UserName> | |||||
| <IconButton | <IconButton | ||||
| style={{ | style={{ | ||||
| background: selectedTheme.primaryIconBackgroundColor, | background: selectedTheme.primaryIconBackgroundColor, |
| export const ToolsContainer = styled(Box)` | export const ToolsContainer = styled(Box)` | ||||
| display: flex; | display: flex; | ||||
| flex-direction: row; | flex-direction: row; | ||||
| justify-content: ${(props) => (props.mobile ? "center" : "space-between")}; | justify-content: ${(props) => (props.mobile ? "center" : "space-between")}; | ||||
| align-items: ${(props) => (props.mobile ? "start" : "center")}; | align-items: ${(props) => (props.mobile ? "start" : "center")}; | ||||
| ${(props) => !props.mobile && `width: 100%;`} | ${(props) => !props.mobile && `width: 100%;`} | ||||
| `; | `; | ||||
| export const ToolsButtonsContainer = styled(Box)` | export const ToolsButtonsContainer = styled(Box)` | ||||
| display: flex; | display: flex; | ||||
| flex: 4; | |||||
| justify-content: space-between; | justify-content: space-between; | ||||
| min-width: ${props => props.mobile ? "40px" : "600px"}; | min-width: ${props => props.mobile ? "40px" : "600px"}; | ||||
| max-width: 600px; | |||||
| align-items: center; | align-items: center; | ||||
| flex-wrap: nowrap; | flex-wrap: nowrap; | ||||
| @media (max-width: 1200px) { | |||||
| min-width: 400px; | |||||
| } | |||||
| @media (max-width: 950px) { | |||||
| min-width: 250px; | |||||
| } | |||||
| @media (max-width: 800px) { | |||||
| min-width: 0px; | |||||
| width: 0px; | |||||
| } | |||||
| `; | `; | ||||
| export const ToggleDrawerButton = styled(Box)` | export const ToggleDrawerButton = styled(Box)` | ||||
| max-width: 40px; | max-width: 40px; |
| HeaderButtons, | HeaderButtons, | ||||
| HeaderContainer, | HeaderContainer, | ||||
| HeaderLocation, | HeaderLocation, | ||||
| // HeaderLocation, | |||||
| HeaderOptions, | HeaderOptions, | ||||
| HeaderSelect, | HeaderSelect, | ||||
| IconStyled, | IconStyled, | ||||
| import { ReactComponent as GridLine } from "../../../assets/images/svg/offer-grid-line.svg"; | import { ReactComponent as GridLine } from "../../../assets/images/svg/offer-grid-line.svg"; | ||||
| import { ReactComponent as Down } from "../../../assets/images/svg/down-arrow.svg"; | import { ReactComponent as Down } from "../../../assets/images/svg/down-arrow.svg"; | ||||
| import selectedTheme from "../../../themes"; | import selectedTheme from "../../../themes"; | ||||
| // import { useSelector } from "react-redux"; | |||||
| // import { selectFilters } from "../../../store/selectors/filtersSelectors"; | |||||
| // import Mockupdata from "../../Cards/FilterCard/Mockupdata"; | |||||
| import Option from "../../Select/Option/Option"; | import Option from "../../Select/Option/Option"; | ||||
| // import { useHistory, useLocation, useRouteMatch } from "react-router-dom"; | |||||
| import { sortEnum } from "../../../enums/sortEnum"; | import { sortEnum } from "../../../enums/sortEnum"; | ||||
| import useFilters from "../../../hooks/useFilters"; | import useFilters from "../../../hooks/useFilters"; | ||||
| import useSorting from "../../../hooks/useSorting"; | |||||
| const DownArrow = (props) => ( | const DownArrow = (props) => ( | ||||
| <IconStyled {...props}> | <IconStyled {...props}> | ||||
| const Header = (props) => { | const Header = (props) => { | ||||
| const filters = useFilters(); | const filters = useFilters(); | ||||
| const sorting = useSorting(); | |||||
| const [sortOption, setSortOption] = useState(sortEnum.INITIAL); | |||||
| const [headerString, setHeaderString] = useState("SVE KATEGORIJE"); | const [headerString, setHeaderString] = useState("SVE KATEGORIJE"); | ||||
| useEffect(() => { | |||||
| setSortOption(sorting.selectedSortOption); | |||||
| }, [sorting.selectedSortOption]); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if (filters.isApplied) { | if (filters.isApplied) { | ||||
| let headerStringLocal = "SVE KATEGORIJE"; | let headerStringLocal = "SVE KATEGORIJE"; | ||||
| if (filters.selectedCategory?.name) { | if (filters.selectedCategory?.name) { | ||||
| console.log(filters.selectedCategory); | |||||
| headerStringLocal = filters.selectedCategory.name; | headerStringLocal = filters.selectedCategory.name; | ||||
| if (filters.selectedSubcategory?.name) { | if (filters.selectedSubcategory?.name) { | ||||
| headerStringLocal += ` | ${filters.selectedSubcategory.name}`; | headerStringLocal += ` | ${filters.selectedSubcategory.name}`; | ||||
| for (const sortOption in sortEnum) { | for (const sortOption in sortEnum) { | ||||
| if (sortEnum[sortOption].value === event.target.value) { | if (sortEnum[sortOption].value === event.target.value) { | ||||
| chosenOption = sortEnum[sortOption]; | chosenOption = sortEnum[sortOption]; | ||||
| filters.setSelectedSortOption(chosenOption); | |||||
| sorting.setSelectedSortOption(chosenOption); | |||||
| } | } | ||||
| } | } | ||||
| }; | }; | ||||
| </HeaderButton> | </HeaderButton> | ||||
| </HeaderButtons> | </HeaderButtons> | ||||
| <HeaderSelect | <HeaderSelect | ||||
| defaultValue={ | |||||
| filters.selectedSortOption ? filters.selectedSortOption.value : 0 | |||||
| } | |||||
| value={sortOption?.value ? sortOption.value : sortEnum.INITIAL.value} | |||||
| IconComponent={DownArrow} | IconComponent={DownArrow} | ||||
| width="209px" | width="209px" | ||||
| height="34px" | height="34px" |
| import { MarketPlaceContainer } from "./MarketPlace.styled"; | import { MarketPlaceContainer } from "./MarketPlace.styled"; | ||||
| import Header from "./Header/Header"; | import Header from "./Header/Header"; | ||||
| import Offers from "./Offers/Offers"; | import Offers from "./Offers/Offers"; | ||||
| import useFilters from "../../hooks/useFilters"; | |||||
| const MarketPlace = () => { | const MarketPlace = () => { | ||||
| const [isGrid, setIsGrid] = useState(false); | const [isGrid, setIsGrid] = useState(false); | ||||
| const filters = useFilters(); | |||||
| return ( | return ( | ||||
| <MarketPlaceContainer> | <MarketPlaceContainer> | ||||
| <Header isGrid={isGrid} setIsGrid={setIsGrid} filters={filters} /> | |||||
| <Header isGrid={isGrid} setIsGrid={setIsGrid} /> | |||||
| <Offers isGrid={isGrid} /> | <Offers isGrid={isGrid} /> | ||||
| </MarketPlaceContainer> | </MarketPlaceContainer> | ||||
| ); | ); |
| import { | import { | ||||
| selectNoMoreOffers, | selectNoMoreOffers, | ||||
| selectOffers, | selectOffers, | ||||
| selectPinnedOffers, | |||||
| } from "../../../store/selectors/offersSelectors"; | } from "../../../store/selectors/offersSelectors"; | ||||
| import useFilters from "../../../hooks/useFilters"; | import useFilters from "../../../hooks/useFilters"; | ||||
| const filters = useFilters(); | const filters = useFilters(); | ||||
| const [page, setPage] = useState(2); | const [page, setPage] = useState(2); | ||||
| const [initialLoad, setInitialLoad] = useState(true); | const [initialLoad, setInitialLoad] = useState(true); | ||||
| const pinnedOffers = useSelector(selectPinnedOffers); | |||||
| const offers = useSelector(selectOffers); | const offers = useSelector(selectOffers); | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const offersRef = useRef(null); | const offersRef = useRef(null); | ||||
| }, [page, noMoreOffersStatus, filters.queryString, timeout, offers]); | }, [page, noMoreOffersStatus, filters.queryString, timeout, offers]); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| setPage(Math.floor(offers.length / 10) + 1); | |||||
| }, [offers]); | |||||
| setPage(Math.floor((offers.length + pinnedOffers.length ) / 10) + 1); | |||||
| }, [offers, pinnedOffers]); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| dispatch(fetchOffers({ page: 1 })); | dispatch(fetchOffers({ page: 1 })); | ||||
| }, [filters.queryString, initialLoad]); | }, [filters.queryString, initialLoad]); | ||||
| return ( | return ( | ||||
| <OffersContainer | |||||
| ref={offersRef} | |||||
| onScroll={() => console.log("proba")} | |||||
| onClick={() => console.log(offersRef)} | |||||
| > | |||||
| <OffersContainer ref={offersRef}> | |||||
| <> | |||||
| {pinnedOffers != undefined && | |||||
| pinnedOffers.map((item) => { | |||||
| return ( | |||||
| <OfferCard key={item._id} offer={item} halfwidth={props.isGrid} /> | |||||
| ); | |||||
| })} | |||||
| </> | |||||
| {offers != undefined && | {offers != undefined && | ||||
| offers.map((item) => { | offers.map((item) => { | ||||
| return ( | return ( |
| import React from "react"; | |||||
| import React, { useEffect } from "react"; | |||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import { useDispatch, useSelector } from "react-redux"; | |||||
| import { fetchChats } from "../../../store/actions/chat/chatActions"; | |||||
| import { selectLatestChats } from "../../../store/selectors/chatSelectors"; | |||||
| import { selectUserId } from "../../../store/selectors/loginSelectors"; | |||||
| import HeaderPopover from "../HeaderPopover/HeaderPopover"; | import HeaderPopover from "../HeaderPopover/HeaderPopover"; | ||||
| const dummyData1 = [ | const dummyData1 = [ | ||||
| alt: "Remy Sharp", | alt: "Remy Sharp", | ||||
| src: "/static/images/avatar/1.jpg", | src: "/static/images/avatar/1.jpg", | ||||
| title: "Coca-Cola", | title: "Coca-Cola", | ||||
| text: "Kompresor je stigao. Samo..." | |||||
| text: "Kompresor je stigao. Samo...", | |||||
| }, | }, | ||||
| { | { | ||||
| alt: "Travis Howard", | alt: "Travis Howard", | ||||
| src: "/static/images/avatar/2.jpg", | src: "/static/images/avatar/2.jpg", | ||||
| title: "Voda Vrnjci", | title: "Voda Vrnjci", | ||||
| text: "Poslao sam vodu. Ukupno i..." | |||||
| } | |||||
| ] | |||||
| text: "Poslao sam vodu. Ukupno i...", | |||||
| }, | |||||
| ]; | |||||
| const convertMessages = (messages) => { | |||||
| const allMessages = [ | |||||
| ...messages.chatsFromMyOffers, | |||||
| ...messages.initiatedChats, | |||||
| ]; | |||||
| const lastMessageDate = Math.max( | |||||
| ...allMessages.map((item) => new Date(item._modified)) | |||||
| ); | |||||
| const lastMessage = allMessages.find( | |||||
| (item) => | |||||
| JSON.stringify(new Date(item._modified)) === | |||||
| JSON.stringify(new Date(lastMessageDate)) | |||||
| ); | |||||
| const lastSecondMessageDate = Math.max([...allMessages.filter(item => item._id !== lastMessage._id).map(item => new Date(item._modified))]) | |||||
| console.log(lastSecondMessageDate); | |||||
| console.log(allMessages.filter(item => item._id !== lastMessage._id).map(item => new Date(item._modified))) | |||||
| console.log(lastMessage); | |||||
| }; | |||||
| export const MyMessages = () => { | export const MyMessages = () => { | ||||
| const {t} = useTranslation(); | |||||
| const { t } = useTranslation(); | |||||
| const dispatch = useDispatch(); | |||||
| const userId = useSelector(selectUserId); | |||||
| const chats = useSelector(selectLatestChats); | |||||
| convertMessages(chats); | |||||
| useEffect(() => { | |||||
| dispatch(fetchChats(userId)); | |||||
| }, []); | |||||
| return ( | return ( | ||||
| <HeaderPopover | <HeaderPopover | ||||
| title={t("header.myMessages")} | title={t("header.myMessages")} | ||||
| items={dummyData1} | items={dummyData1} | ||||
| buttonText={t("header.checkEverything")} /> | |||||
| buttonText={t("header.checkEverything")} | |||||
| /> | |||||
| ); | ); | ||||
| }; | }; |
| import React, { useEffect } from 'react'; | import React, { useEffect } from 'react'; | ||||
| import { Redirect, Route } from 'react-router'; | import { Redirect, Route } from 'react-router'; | ||||
| import { useDispatch } from 'react-redux'; | |||||
| import { useDispatch, useSelector } from 'react-redux'; | |||||
| import { authenticateUser } from '../../store/actions/login/loginActions'; | import { authenticateUser } from '../../store/actions/login/loginActions'; | ||||
| // import { selectIsUserAuthenticated } from '../../store/selectors/userSelectors'; | // import { selectIsUserAuthenticated } from '../../store/selectors/userSelectors'; | ||||
| import { LOGIN_PAGE } from '../../constants/pages'; | import { LOGIN_PAGE } from '../../constants/pages'; | ||||
| import { fetchProfile } from '../../store/actions/profile/profileActions'; | |||||
| import { selectUserId } from '../../store/selectors/loginSelectors'; | |||||
| const PrivateRoute = ({ ...props }) => { | const PrivateRoute = ({ ...props }) => { | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const userId = useSelector(selectUserId); | |||||
| // const isUserAuthenticated = useSelector(selectIsUserAuthenticated); | // const isUserAuthenticated = useSelector(selectIsUserAuthenticated); | ||||
| const isUserAuthenticated = true; | const isUserAuthenticated = true; | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (!isUserAuthenticated) { | if (!isUserAuthenticated) { | ||||
| dispatch(authenticateUser()); | dispatch(authenticateUser()); | ||||
| } else { | |||||
| dispatch(fetchProfile(userId)) | |||||
| } | } | ||||
| }, [isUserAuthenticated]); // eslint-disable-line | }, [isUserAuthenticated]); // eslint-disable-line | ||||
| import { OptionIcon, OptionStyled } from './Option.styled' | import { OptionIcon, OptionStyled } from './Option.styled' | ||||
| const Option = props => { | const Option = props => { | ||||
| console.log(props) | |||||
| return ( | return ( | ||||
| <OptionStyled {...props} value={props.value} > | <OptionStyled {...props} value={props.value} > | ||||
| {props.startIcon ? ( | {props.startIcon ? ( |
| fullWidth={props.fullwidth} | fullWidth={props.fullwidth} | ||||
| open={isOpened} | open={isOpened} | ||||
| onClick={() => handleOpen()} | onClick={() => handleOpen()} | ||||
| value={props.value} | |||||
| width={props.width} | width={props.width} | ||||
| height={props.height} | height={props.height} | ||||
| className={props.className} | className={props.className} | ||||
| defaultValue: PropTypes.number, | defaultValue: PropTypes.number, | ||||
| className: PropTypes.string, | className: PropTypes.string, | ||||
| onChange: PropTypes.func, | onChange: PropTypes.func, | ||||
| value: PropTypes.any, | |||||
| }; | }; | ||||
| Select.defaultProps = { | Select.defaultProps = { | ||||
| fullwidth: true, | fullwidth: true, |
| import React, { useEffect, useRef, useState } from "react"; | |||||
| import React, { useEffect, useState } from "react"; | |||||
| import { TextFieldContainer, TextFieldStyled } from "./TextField.styled"; | import { TextFieldContainer, TextFieldStyled } from "./TextField.styled"; | ||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||
| export const TextField = (props) => { | |||||
| export const TextField = React.forwardRef((props, ref) => { | |||||
| const [isFieldEmpty, setIsFieldEmpty] = useState(true); | const [isFieldEmpty, setIsFieldEmpty] = useState(true); | ||||
| // for italicPlaceholder | // for italicPlaceholder | ||||
| setIsFieldEmpty(false); | setIsFieldEmpty(false); | ||||
| } | } | ||||
| }, [props.value]); | }, [props.value]); | ||||
| const textInputRef = useRef(); | |||||
| return ( | return ( | ||||
| <TextFieldContainer | <TextFieldContainer | ||||
| height={props.height} | height={props.height} | ||||
| > | > | ||||
| <TextFieldStyled | <TextFieldStyled | ||||
| inputRef={ref} | |||||
| placeholder={props.placeholder} | placeholder={props.placeholder} | ||||
| width={props.width} | width={props.width} | ||||
| height={props.height} | height={props.height} | ||||
| italicplaceholder={(props.italicPlaceholder && isFieldEmpty) ? "true" : "false"} | italicplaceholder={(props.italicPlaceholder && isFieldEmpty) ? "true" : "false"} | ||||
| ref={textInputRef} | |||||
| focused={props.focused} | focused={props.focused} | ||||
| > | > | ||||
| {props.children} | {props.children} | ||||
| </TextFieldStyled> | </TextFieldStyled> | ||||
| </TextFieldContainer> | </TextFieldContainer> | ||||
| ); | ); | ||||
| }; | |||||
| }); | |||||
| TextField.displayName = "TextField"; | |||||
| TextField.propTypes = { | TextField.propTypes = { | ||||
| history: PropTypes.shape({ | history: PropTypes.shape({ | ||||
| ref: PropTypes.any, | ref: PropTypes.any, | ||||
| minRows: PropTypes.number, | minRows: PropTypes.number, | ||||
| multiline: PropTypes.bool, | multiline: PropTypes.bool, | ||||
| onFocus: PropTypes.onFocus, | |||||
| onBlur: PropTypes.onBlur, | |||||
| onFocus: PropTypes.func, | |||||
| onBlur: PropTypes.func, | |||||
| focused: PropTypes.bool, | focused: PropTypes.bool, | ||||
| InputProps: PropTypes.shape({ | InputProps: PropTypes.shape({ | ||||
| startAdornment: PropTypes.node, | startAdornment: PropTypes.node, |
| import { useDispatch } from "react-redux"; | import { useDispatch } from "react-redux"; | ||||
| import { useSelector } from "react-redux"; | import { useSelector } from "react-redux"; | ||||
| import { useHistory } from "react-router-dom"; | import { useHistory } from "react-router-dom"; | ||||
| import { sortEnum } from "../enums/sortEnum"; | |||||
| import { fetchCategories } from "../store/actions/categories/categoriesActions"; | import { fetchCategories } from "../store/actions/categories/categoriesActions"; | ||||
| import { | import { | ||||
| setFilteredCategory, | setFilteredCategory, | ||||
| setFilteredLocations, | setFilteredLocations, | ||||
| setFilteredSortOption, | |||||
| setFilteredSubcategory, | setFilteredSubcategory, | ||||
| setIsAppliedStatus, | setIsAppliedStatus, | ||||
| setQueryString, | |||||
| } from "../store/actions/filters/filtersActions"; | } from "../store/actions/filters/filtersActions"; | ||||
| import { fetchLocations } from "../store/actions/locations/locationsActions"; | import { fetchLocations } from "../store/actions/locations/locationsActions"; | ||||
| import { | import { | ||||
| } from "../store/selectors/categoriesSelectors"; | } from "../store/selectors/categoriesSelectors"; | ||||
| import { | import { | ||||
| selectAppliedStatus, | selectAppliedStatus, | ||||
| selectQueryString, | |||||
| selectSelectedCategory, | selectSelectedCategory, | ||||
| selectSelectedLocations, | selectSelectedLocations, | ||||
| selectSelectedSortOption, | |||||
| selectSelectedSubcategory, | selectSelectedSubcategory, | ||||
| } from "../store/selectors/filtersSelectors"; | } from "../store/selectors/filtersSelectors"; | ||||
| import qs from "query-string"; | import qs from "query-string"; | ||||
| import { selectLocations } from "../store/selectors/locationsSelectors"; | import { selectLocations } from "../store/selectors/locationsSelectors"; | ||||
| import { fetchOffers } from "../store/actions/offers/offersActions"; | import { fetchOffers } from "../store/actions/offers/offersActions"; | ||||
| import { HOME_PAGE } from "../constants/pages"; | import { HOME_PAGE } from "../constants/pages"; | ||||
| import { convertQueryString } from "../util/helpers/queryHelpers"; | |||||
| const useFilters = () => { | const useFilters = () => { | ||||
| const [queryString, setQueryString] = useState(); | |||||
| const queryString = useSelector(selectQueryString); | |||||
| const selectedCategory = useSelector(selectSelectedCategory); | const selectedCategory = useSelector(selectSelectedCategory); | ||||
| const selectedSubcategory = useSelector(selectSelectedSubcategory); | const selectedSubcategory = useSelector(selectSelectedSubcategory); | ||||
| const selectedLocations = useSelector(selectSelectedLocations); | const selectedLocations = useSelector(selectSelectedLocations); | ||||
| const selectedSortOption = useSelector(selectSelectedSortOption); | |||||
| const [loadedFromQS, setLoadedFromQS] = useState(false); | const [loadedFromQS, setLoadedFromQS] = useState(false); | ||||
| const [loaded, setLoadedStatus] = useState(false); | const [loaded, setLoadedStatus] = useState(false); | ||||
| const isApplied = useSelector(selectAppliedStatus); | const isApplied = useSelector(selectAppliedStatus); | ||||
| selectSubcategories(selectedCategory?.name) | selectSubcategories(selectedCategory?.name) | ||||
| ); | ); | ||||
| const locations = useSelector(selectLocations); | const locations = useSelector(selectLocations); | ||||
| const sortOptions = sortEnum; | |||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (!loaded) { | if (!loaded) { | ||||
| setSelectedLocations([...locationsToPush]); | setSelectedLocations([...locationsToPush]); | ||||
| } | } | ||||
| // For future changes if needed | // For future changes if needed | ||||
| if (queryObject._des_date || queryObject._des_popular) { | |||||
| if (queryObject._des_date === "false") { | |||||
| setSelectedSortOption(sortOptions.OLD); | |||||
| } | |||||
| if (queryObject._des_date === "true") { | |||||
| setSelectedSortOption(sortOptions.NEW); | |||||
| } | |||||
| if (queryObject._des_popular === "true") { | |||||
| setSelectedSortOption(sortOptions.POPULAR); | |||||
| } | |||||
| } | |||||
| // if (queryObject.sortBy) { | |||||
| // if (queryObject.sortBy === sortOptions.OLD.queryString) { | |||||
| // setSelectedSortOption(sortOptions.OLD); | |||||
| // } | |||||
| // if (queryObject.sortBy === sortOptions.NEW.queryString) { | |||||
| // setSelectedSortOption(sortOptions.NEW); | |||||
| // } | |||||
| // if (queryObject.sortBy === sortOptions.POPULAR.queryString) { | |||||
| // setSelectedSortOption(sortOptions.POPULAR); | |||||
| // } | |||||
| // } | |||||
| setLoadedFromQS(true); | setLoadedFromQS(true); | ||||
| dispatch(setIsAppliedStatus(true)); | dispatch(setIsAppliedStatus(true)); | ||||
| } | } | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (loadedFromQS) { | if (loadedFromQS) { | ||||
| let qsArray = []; | |||||
| if (selectedCategory && selectedCategory?._id !== 0) { | |||||
| qsArray.push("category=" + encodeURIComponent(selectedCategory.name)); | |||||
| } | |||||
| if (selectedSubcategory && selectedSubcategory?._id !== 0) { | |||||
| qsArray.push( | |||||
| "subcategory=" + encodeURIComponent(selectedSubcategory.name) | |||||
| ); | |||||
| } | |||||
| if (selectedLocations && selectedLocations?.length > 0) { | |||||
| selectedLocations.forEach((location) => { | |||||
| qsArray.push("location=" + encodeURIComponent(location.city)); | |||||
| }); | |||||
| } | |||||
| if (selectedSortOption) { | |||||
| let _des_date = null; | |||||
| let _des_popular = null; | |||||
| if (selectedSortOption === sortOptions.NEW) { | |||||
| _des_date = true; | |||||
| } | |||||
| if (selectedSortOption === sortOptions.OLD) { | |||||
| _des_date = false; | |||||
| } | |||||
| if (selectedSortOption === sortOptions.POPULAR) { | |||||
| _des_popular = true; | |||||
| } | |||||
| if (_des_date !== null) | |||||
| qsArray.push("_des_date=" + encodeURIComponent(_des_date)); | |||||
| if (_des_popular !== null) | |||||
| qsArray.push("_des_popular=" + encodeURIComponent(_des_popular)); | |||||
| } | |||||
| let qsStringFromArray = "?" + qsArray.join("&"); | |||||
| console.log(qsStringFromArray); | |||||
| setQueryString(qsStringFromArray); | |||||
| makeQueryString(); | |||||
| } | } | ||||
| }, [ | }, [ | ||||
| selectedCategory, | selectedCategory, | ||||
| selectedLocations, | selectedLocations, | ||||
| selectedSortOption, | |||||
| selectedSubcategory, | selectedSubcategory, | ||||
| loadedFromQS, | loadedFromQS, | ||||
| ]); | ]); | ||||
| useEffect(() => { | |||||
| console.log("QS: ", queryString); | |||||
| }, [queryString]); | |||||
| // Apply everything | |||||
| const applyFilters = () => { | const applyFilters = () => { | ||||
| dispatch(setIsAppliedStatus(true)); | dispatch(setIsAppliedStatus(true)); | ||||
| dispatch(fetchOffers({ queryString: queryString })); | dispatch(fetchOffers({ queryString: queryString })); | ||||
| history.push({ | history.push({ | ||||
| pathname: HOME_PAGE, | pathname: HOME_PAGE, | ||||
| search: queryString, | |||||
| search: convertQueryString(queryString), | |||||
| }); | }); | ||||
| window.scrollTo({ | window.scrollTo({ | ||||
| top: 0, | top: 0, | ||||
| }); | }); | ||||
| }; | }; | ||||
| // Clear function | |||||
| const clearFilters = () => { | const clearFilters = () => { | ||||
| setSelectedLocations([]); | setSelectedLocations([]); | ||||
| setSelectedSubcategory(); | setSelectedSubcategory(); | ||||
| setSelectedCategory(); | setSelectedCategory(); | ||||
| }; | }; | ||||
| // Helper function | |||||
| const makeQueryString = () => { | |||||
| let qsArray = []; | |||||
| if (selectedCategory && selectedCategory?._id !== 0) { | |||||
| qsArray.push("category=" + encodeURIComponent(selectedCategory.name)); | |||||
| } | |||||
| if (selectedSubcategory && selectedSubcategory?._id !== 0) { | |||||
| qsArray.push( | |||||
| "subcategory=" + encodeURIComponent(selectedSubcategory.name) | |||||
| ); | |||||
| } | |||||
| if (selectedLocations && selectedLocations?.length > 0) { | |||||
| selectedLocations.forEach((location) => { | |||||
| qsArray.push("location=" + encodeURIComponent(location.city)); | |||||
| }); | |||||
| } | |||||
| let qsStringFromArray = "?" + qsArray.join("&"); | |||||
| // if (queryString.length > 1) { | |||||
| // dispatch(setQueryString(queryString + "&" + qsStringFromArray)); | |||||
| // } else { | |||||
| // let queryStringEdited = new URLSearchParams(qsStringFromArray); | |||||
| dispatch(setQueryString(qsStringFromArray)); | |||||
| // } | |||||
| }; | |||||
| // Setters | |||||
| const setSelectedCategory = (payload) => { | const setSelectedCategory = (payload) => { | ||||
| if (isApplied !== false) { | if (isApplied !== false) { | ||||
| dispatch(setIsAppliedStatus(false)); | dispatch(setIsAppliedStatus(false)); | ||||
| } | } | ||||
| dispatch(setFilteredLocations(payload)); | dispatch(setFilteredLocations(payload)); | ||||
| }; | }; | ||||
| const setSelectedSortOption = (payload) => { | |||||
| if (isApplied !== false) { | |||||
| dispatch(setIsAppliedStatus(false)); | |||||
| } | |||||
| dispatch(setFilteredSortOption(payload)); | |||||
| }; | |||||
| return { | return { | ||||
| selectedCategory, | selectedCategory, | ||||
| setSelectedCategory, | setSelectedCategory, | ||||
| setSelectedSubcategory, | setSelectedSubcategory, | ||||
| selectedLocations, | selectedLocations, | ||||
| setSelectedLocations, | setSelectedLocations, | ||||
| selectedSortOption, | |||||
| setSelectedSortOption, | |||||
| categories, | categories, | ||||
| subcategories, | subcategories, | ||||
| locations, | locations, | ||||
| sortOptions, | |||||
| queryString, | queryString, | ||||
| applyFilters, | applyFilters, | ||||
| clearFilters, | clearFilters, | ||||
| isApplied, | isApplied, | ||||
| makeQueryString | |||||
| }; | }; | ||||
| }; | }; | ||||
| import { useDispatch, useSelector } from "react-redux"; | |||||
| import { fetchOffers } from "../store/actions/offers/offersActions"; | |||||
| import { selectQueryString } from "../store/selectors/filtersSelectors"; | |||||
| export const useSearch = () => { | |||||
| const dispatch = useDispatch(); | |||||
| const queryString = useSelector(selectQueryString); | |||||
| const searchOffers = (searchString) => { | |||||
| const queryObject = new URLSearchParams(queryString); | |||||
| queryObject.set('oname', searchString); | |||||
| dispatch(fetchOffers({queryString: "?" + queryObject.toString()})); | |||||
| } | |||||
| return { | |||||
| searchOffers | |||||
| } | |||||
| } |
| import { useEffect, useState } from "react"; | |||||
| import { useDispatch, useSelector } from "react-redux"; | |||||
| import { useHistory } from "react-router-dom"; | |||||
| import { HOME_PAGE } from "../constants/pages"; | |||||
| import { sortEnum } from "../enums/sortEnum"; | |||||
| import { setFilteredSortOption} from "../store/actions/filters/filtersActions"; | |||||
| import { fetchOffers } from "../store/actions/offers/offersActions"; | |||||
| import qs from "query-string"; | |||||
| import { | |||||
| selectQueryString, | |||||
| selectSelectedSortOption, | |||||
| } from "../store/selectors/filtersSelectors"; | |||||
| import useFilters from "./useFilters"; | |||||
| const useSorting = () => { | |||||
| // Local query string is query string used for fetching data from API | |||||
| const [localQueryString, setLocalQueryString] = useState(""); | |||||
| // Global query string is query string shown for user (more user-friendly) | |||||
| const [globalQueryString, setGlobalQueryString] = useState(""); | |||||
| const history = useHistory(); | |||||
| const filters = useFilters(); | |||||
| const queryString = useSelector(selectQueryString); | |||||
| const dispatch = useDispatch(); | |||||
| const selectedSortOption = useSelector(selectSelectedSortOption); | |||||
| const sortOptions = sortEnum; | |||||
| useEffect(() => { | |||||
| if (localQueryString.length > 0) { | |||||
| if (queryString.length > 1) { | |||||
| let queryStringEdited = new URLSearchParams(queryString); | |||||
| queryStringEdited.delete('_des_date'); | |||||
| queryStringEdited.delete('_des_popular'); | |||||
| dispatch( | |||||
| fetchOffers({ queryString: "?" + queryStringEdited + "&" + localQueryString }) | |||||
| ); | |||||
| history.push({ | |||||
| pathname: HOME_PAGE, | |||||
| search: "?" + queryStringEdited + "&" + globalQueryString, | |||||
| }); | |||||
| } else { | |||||
| dispatch(fetchOffers({queryString: "?" + localQueryString})); | |||||
| history.push({ | |||||
| pathname: HOME_PAGE, | |||||
| search: "?" + globalQueryString, | |||||
| }); | |||||
| } | |||||
| window.scrollTo({ | |||||
| top: 0, | |||||
| behavior: "smooth", | |||||
| }); | |||||
| } | |||||
| }, [localQueryString]); | |||||
| useEffect(() => { | |||||
| const queryStringFromUrl = history.location.search.substring(1); | |||||
| const queryObjectFromUrl = qs.parse(queryStringFromUrl); | |||||
| if (queryObjectFromUrl?.sortBy) { | |||||
| if (queryObjectFromUrl.sortBy === sortOptions.OLD.queryString) { | |||||
| setSelectedSortOption(sortOptions.OLD) | |||||
| } | |||||
| if (queryObjectFromUrl.sortBy === sortOptions.NEW.queryString) { | |||||
| setSelectedSortOption(sortOptions.NEW) | |||||
| } | |||||
| if (queryObjectFromUrl.sortBy === sortOptions.POPULAR.queryString) { | |||||
| setSelectedSortOption(sortOptions.POPULAR) | |||||
| } | |||||
| } else { | |||||
| setSelectedSortOption(sortOptions.INITIAL) | |||||
| } | |||||
| setGlobalQueryString(qs.stringify(queryObjectFromUrl)); | |||||
| filters.makeQueryString(); | |||||
| }, [history.location.search]); | |||||
| const setSelectedSortOption = (payload) => { | |||||
| dispatch(setFilteredSortOption(payload)); | |||||
| let _des_date = null; | |||||
| let _des_popular = null; | |||||
| if (payload === sortOptions.NEW) { | |||||
| setGlobalQueryString(`sortBy=${sortOptions.NEW.queryString}`); | |||||
| _des_date = true; | |||||
| } | |||||
| if (payload === sortOptions.OLD) { | |||||
| setGlobalQueryString(`sortBy=${sortOptions.OLD.queryString}`); | |||||
| _des_date = false; | |||||
| } | |||||
| if (payload === sortOptions.POPULAR) { | |||||
| setGlobalQueryString(`sortBy=${sortOptions.POPULAR.queryString}`); | |||||
| _des_popular = true; | |||||
| } | |||||
| if (_des_date !== null) { | |||||
| setLocalQueryString(`_des_date=${_des_date}`); | |||||
| } | |||||
| if (_des_popular !== null) { | |||||
| setLocalQueryString(`_des_popular=${_des_popular}`); | |||||
| } | |||||
| }; | |||||
| return { | |||||
| selectedSortOption, | |||||
| setSelectedSortOption, | |||||
| sortOptions, | |||||
| }; | |||||
| }; | |||||
| export default useSorting; |
| display: flex; | display: flex; | ||||
| flex: 1; | flex: 1; | ||||
| height: 100%; | height: 100%; | ||||
| margin-top: 80px; | |||||
| ` | ` | ||||
| export const LeftCard = styled(Grid)` | export const LeftCard = styled(Grid)` |
| max-width: none; | max-width: none; | ||||
| flex: 1; | flex: 1; | ||||
| height: 100%; | height: 100%; | ||||
| margin-top: 80px; | |||||
| ` | ` | ||||
| export const LeftCard = styled(Grid)` | export const LeftCard = styled(Grid)` |
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import { | import { | ||||
| clearLoginErrors, | clearLoginErrors, | ||||
| fetchUser, | |||||
| fetchLogin, | |||||
| } from "../../store/actions/login/loginActions"; | } from "../../store/actions/login/loginActions"; | ||||
| import { selectLoginError } from "../../store/selectors/loginSelectors"; | |||||
| import { selectLoginError, selectUserId } from "../../store/selectors/loginSelectors"; | |||||
| import { FORGOT_PASSWORD_PAGE, HOME_PAGE } from "../../constants/pages"; | import { FORGOT_PASSWORD_PAGE, HOME_PAGE } from "../../constants/pages"; | ||||
| import { ReactComponent as VisibilityOn } from "../../assets/images/svg/eye-striked.svg"; | import { ReactComponent as VisibilityOn } from "../../assets/images/svg/eye-striked.svg"; | ||||
| import { ReactComponent as VisibilityOff } from "../../assets/images/svg/eye.svg"; | import { ReactComponent as VisibilityOff } from "../../assets/images/svg/eye.svg"; | ||||
| import selectedTheme from "../../themes"; | import selectedTheme from "../../themes"; | ||||
| import loginValidation from "../../validations/loginValidation"; | import loginValidation from "../../validations/loginValidation"; | ||||
| import loginInitialValues from "../../initialValues/loginInitialValues"; | import loginInitialValues from "../../initialValues/loginInitialValues"; | ||||
| import { fetchProfile } from "../../store/actions/profile/profileActions"; | |||||
| const LoginPage = ({ history }) => { | const LoginPage = ({ history }) => { | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| const error = useSelector(selectLoginError); | const error = useSelector(selectLoginError); | ||||
| const userId = useSelector(selectUserId); | |||||
| const [showPassword, setShowPassword] = useState(false); | const [showPassword, setShowPassword] = useState(false); | ||||
| const handleClickShowPassword = () => setShowPassword(!showPassword); | const handleClickShowPassword = () => setShowPassword(!showPassword); | ||||
| }, []); | }, []); | ||||
| const handleApiResponseSuccess = () => { | const handleApiResponseSuccess = () => { | ||||
| dispatch(fetchProfile(userId)) | |||||
| history.push({ | history.push({ | ||||
| pathname: HOME_PAGE, | pathname: HOME_PAGE, | ||||
| state: { | state: { | ||||
| }; | }; | ||||
| const handleSubmit = (values) => { | const handleSubmit = (values) => { | ||||
| const { email, password: password } = values; | |||||
| const { email, password } = values; | |||||
| dispatch(clearLoginErrors()); | dispatch(clearLoginErrors()); | ||||
| dispatch( | dispatch( | ||||
| fetchUser({ | |||||
| fetchLogin({ | |||||
| email, | email, | ||||
| password, | password, | ||||
| handleApiResponseSuccess, | handleApiResponseSuccess, |
| '/users?fp={fp}&offer={offer}&landingPageUrl={landingPageUrl}®istrationFlowType={registrationFlowType}', | '/users?fp={fp}&offer={offer}&landingPageUrl={landingPageUrl}®istrationFlowType={registrationFlowType}', | ||||
| updateUserRegistration: '/users/{userUid}', | updateUserRegistration: '/users/{userUid}', | ||||
| invite: '/users/invite', | invite: '/users/invite', | ||||
| getProfile: 'users/' | |||||
| }, | }, | ||||
| applications: { | applications: { | ||||
| application: '/applications/{applicationUid}', | application: '/applications/{applicationUid}', |
| import { getRequest } from "." | |||||
| export const attemptFetchChats = (payload) => { | |||||
| return getRequest(`users/${payload}/chat`); | |||||
| } |
| }); | }); | ||||
| export const getRequest = (url, params = null, options = null) => { | export const getRequest = (url, params = null, options = null) => { | ||||
| console.log('url: ', url); | |||||
| return request.get(url, { params, ...options }); | return request.get(url, { params, ...options }); | ||||
| } | } | ||||
| import { getRequest } from "."; | |||||
| import apiEndpoints from "./apiEndpoints"; | |||||
| export const attemptFetchProfile = (payload) => | |||||
| getRequest(apiEndpoints.users.getProfile + payload); |
| import { createFetchType } from "../actionHelpers"; | |||||
| const CHAT_SCOPE = "CHAT_SCOPE"; | |||||
| export const CHAT_FETCH = createFetchType(CHAT_SCOPE); | |||||
| export const CHAT_SET = "CHAT_SET"; |
| import { CHAT_FETCH, CHAT_SET } from "./chatActionConstants"; | |||||
| export const fetchChats = (payload) => ({ | |||||
| type: CHAT_FETCH, | |||||
| payload, | |||||
| }) | |||||
| export const setChats = (payload) => ({ | |||||
| type: CHAT_SET, | |||||
| payload, | |||||
| }) |
| export const SET_LOCATIONS = "FILTERS_SET_LOCATIONS"; | export const SET_LOCATIONS = "FILTERS_SET_LOCATIONS"; | ||||
| export const SET_SORT_OPTION = "FILTERS_SET_SORT_OPTION"; | export const SET_SORT_OPTION = "FILTERS_SET_SORT_OPTION"; | ||||
| export const SET_IS_APPLIED = "FILTERS_SET_IS_APPLIED"; | export const SET_IS_APPLIED = "FILTERS_SET_IS_APPLIED"; | ||||
| export const SET_QUERY_STRING = "FILTERS_SET_QUERY_STRING"; |
| import { CLEAR_FILTERS, SET_CATEGORY, SET_FILTERS, SET_IS_APPLIED, SET_LOCATIONS, SET_SORT_OPTION, SET_SUBCATEGORY } from "./filtersActionConstants"; | |||||
| import { CLEAR_FILTERS, SET_CATEGORY, SET_FILTERS, SET_IS_APPLIED, SET_LOCATIONS, SET_QUERY_STRING, SET_SORT_OPTION, SET_SUBCATEGORY } from "./filtersActionConstants"; | |||||
| export const setFilters = (payload) => ({ | export const setFilters = (payload) => ({ | ||||
| type: SET_FILTERS, | type: SET_FILTERS, | ||||
| export const setIsAppliedStatus = (payload) => ({ | export const setIsAppliedStatus = (payload) => ({ | ||||
| type: SET_IS_APPLIED, | type: SET_IS_APPLIED, | ||||
| payload, | payload, | ||||
| }) | |||||
| export const setQueryString = (payload) => ({ | |||||
| type: SET_QUERY_STRING, | |||||
| payload, | |||||
| }) | }) |
| } from './loginActionConstants'; | } from './loginActionConstants'; | ||||
| export const fetchUser = (payload) => ({ | |||||
| export const fetchLogin = (payload) => ({ | |||||
| type: LOGIN_USER_FETCH, | type: LOGIN_USER_FETCH, | ||||
| payload, | payload, | ||||
| }); | }); |
| import { createClearType, createErrorType, createFetchType, createSuccessType } from "../actionHelpers"; | import { createClearType, createErrorType, createFetchType, createSuccessType } from "../actionHelpers"; | ||||
| const OFFERS_SCOPE = "OFFERS_SCOPE"; | const OFFERS_SCOPE = "OFFERS_SCOPE"; | ||||
| const OFFERS_MORE_SCOPE = "OFFERS_MORE_SCOPE"; | const OFFERS_MORE_SCOPE = "OFFERS_MORE_SCOPE"; | ||||
| export const OFFERS_FETCH_MORE = createFetchType(OFFERS_MORE_SCOPE); | export const OFFERS_FETCH_MORE = createFetchType(OFFERS_MORE_SCOPE); | ||||
| export const OFFERS_ERROR = createErrorType(OFFERS_SCOPE); | export const OFFERS_ERROR = createErrorType(OFFERS_SCOPE); | ||||
| export const OFFERS_CLEAR = createClearType(OFFERS_SCOPE); | export const OFFERS_CLEAR = createClearType(OFFERS_SCOPE); | ||||
| export const OFFERS_PINNED_SET = "OFFERS_PINNED_SET"; | |||||
| export const OFFERS_PINNED_ADD = "OFFERS_PINNED_ADD"; | |||||
| export const OFFERS_SET = "OFFERS_SET"; | export const OFFERS_SET = "OFFERS_SET"; | ||||
| export const OFFERS_ADD = "OFFERS_ADD"; | export const OFFERS_ADD = "OFFERS_ADD"; | ||||
| export const OFFER_ADD = "OFFER_ADD"; | |||||
| export const OFFERS_NO_MORE = "OFFERS_NO_MORE"; | export const OFFERS_NO_MORE = "OFFERS_NO_MORE"; |
| import { OFFERS_ADD, OFFERS_CLEAR, OFFERS_ERROR, OFFERS_FETCH, OFFERS_FETCH_MORE, OFFERS_NO_MORE, OFFERS_SET, OFFERS_SUCCESS, OFFER_ADD } from "./offersActionConstants"; | |||||
| import { OFFERS_ADD, OFFERS_CLEAR, OFFERS_ERROR, OFFERS_FETCH, OFFERS_FETCH_MORE, OFFERS_NO_MORE, OFFERS_PINNED_ADD, OFFERS_PINNED_SET, OFFERS_SET, OFFERS_SUCCESS} from "./offersActionConstants"; | |||||
| export const fetchOffers = (payload) => ({ | export const fetchOffers = (payload) => ({ | ||||
| type: OFFERS_FETCH, | type: OFFERS_FETCH, | ||||
| type: OFFERS_SET, | type: OFFERS_SET, | ||||
| payload, | payload, | ||||
| }) | }) | ||||
| export const addOffers = (payload) => ({ | |||||
| type: OFFERS_ADD, | |||||
| export const setPinnedOffers = (payload) => ({ | |||||
| type: OFFERS_PINNED_SET, | |||||
| payload | payload | ||||
| }) | }) | ||||
| export const addOffer = (payload) => ({ | |||||
| type: OFFER_ADD, | |||||
| export const addPinnedOffers = (payload) => ({ | |||||
| type: OFFERS_PINNED_ADD, | |||||
| payload, | |||||
| }) | |||||
| export const addOffers = (payload) => ({ | |||||
| type: OFFERS_ADD, | |||||
| payload | payload | ||||
| }) | }) | ||||
| export const fetchMoreOffers = (payload) => ({ | export const fetchMoreOffers = (payload) => ({ |
| import { createErrorType, createFetchType, createSuccessType } from "../actionHelpers"; | |||||
| const PROFILE_SCOPE = "PROFILE_SCOPE"; | |||||
| export const PROFILE_FETCH = createFetchType(PROFILE_SCOPE); | |||||
| export const PROFILE_SUCCESS = createSuccessType(PROFILE_SCOPE); | |||||
| export const PROFILE_ERROR = createErrorType(PROFILE_SCOPE); | |||||
| export const PROFILE_SET = "PROFILE_SET"; |
| import { PROFILE_ERROR, PROFILE_FETCH, PROFILE_SET, PROFILE_SUCCESS } from "./profileActionConstants"; | |||||
| export const fetchProfile = (payload) => ({ | |||||
| type: PROFILE_FETCH, | |||||
| payload | |||||
| }) | |||||
| export const fetchSuccessProfile = (payload) => ({ | |||||
| type: PROFILE_SUCCESS, | |||||
| payload, | |||||
| }) | |||||
| export const fetchErrorProfile = (payload) => ({ | |||||
| type: PROFILE_ERROR, | |||||
| payload, | |||||
| }) | |||||
| export const setProfile = (payload) => ({ | |||||
| type: PROFILE_SET, | |||||
| payload, | |||||
| }) |
| import { CHAT_SET } from "../../actions/chat/chatActionConstants" | |||||
| import createReducer from "../../utils/createReducer" | |||||
| const initialState = { | |||||
| latestChats: [], | |||||
| } | |||||
| export default createReducer( | |||||
| { | |||||
| [CHAT_SET]: setChats, | |||||
| }, | |||||
| initialState | |||||
| ) | |||||
| function setChats(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| latestChats: action.payload | |||||
| } | |||||
| } |
| SET_FILTERS, | SET_FILTERS, | ||||
| SET_IS_APPLIED, | SET_IS_APPLIED, | ||||
| SET_LOCATIONS, | SET_LOCATIONS, | ||||
| SET_QUERY_STRING, | |||||
| SET_SORT_OPTION, | SET_SORT_OPTION, | ||||
| SET_SUBCATEGORY, | SET_SUBCATEGORY, | ||||
| } from "../../actions/filters/filtersActionConstants"; | } from "../../actions/filters/filtersActionConstants"; | ||||
| locations: [], | locations: [], | ||||
| sortOption: null, | sortOption: null, | ||||
| isApplied: false, | isApplied: false, | ||||
| queryString: "", | |||||
| }, | }, | ||||
| }; | }; | ||||
| [SET_LOCATIONS]: setFilteredLocations, | [SET_LOCATIONS]: setFilteredLocations, | ||||
| [SET_SORT_OPTION]: setFilteredSortOption, | [SET_SORT_OPTION]: setFilteredSortOption, | ||||
| [SET_IS_APPLIED]: setIsAppliedStatus, | [SET_IS_APPLIED]: setIsAppliedStatus, | ||||
| [SET_QUERY_STRING]: setQueryString, | |||||
| }, | }, | ||||
| initialState | initialState | ||||
| ); | ); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| function setQueryString(state, {payload}) { | |||||
| return { | |||||
| ...state, | |||||
| filters: { | |||||
| ...state.filters, | |||||
| queryString: payload, | |||||
| } | |||||
| } | |||||
| } |
| import offersReducer from "./offers/offersReducer"; | import offersReducer from "./offers/offersReducer"; | ||||
| import categoriesReducer from "./categories/categoriesReducer"; | import categoriesReducer from "./categories/categoriesReducer"; | ||||
| import locationsReducer from "./locations/locationsReducer"; | import locationsReducer from "./locations/locationsReducer"; | ||||
| import profileReducer from "./profile/profileReducer"; | |||||
| import chatReducer from "./chat/chatReducer"; | |||||
| const loginPersistConfig = { | const loginPersistConfig = { | ||||
| key: "login", | key: "login", | ||||
| storage: storage, | storage: storage, | ||||
| transform: [createFilter("locations", ["_id", "city"])], | transform: [createFilter("locations", ["_id", "city"])], | ||||
| }; | }; | ||||
| const profilePersistConfig = { | |||||
| key: "profile", | |||||
| storage: storage, | |||||
| transform: [createFilter("profile", ["profile"])], | |||||
| }; | |||||
| const chatPersistConfig = { | |||||
| key: "chat", | |||||
| storage: storage, | |||||
| transform: [createFilter("chat", ["latestChats"])] | |||||
| } | |||||
| export default combineReducers({ | export default combineReducers({ | ||||
| login: persistReducer(loginPersistConfig, loginReducer), | login: persistReducer(loginPersistConfig, loginReducer), | ||||
| offers: offersReducer, | offers: offersReducer, | ||||
| categories: persistReducer(categoriesPersistConfig, categoriesReducer), | categories: persistReducer(categoriesPersistConfig, categoriesReducer), | ||||
| locations: persistReducer(locationsPersistConfig, locationsReducer), | locations: persistReducer(locationsPersistConfig, locationsReducer), | ||||
| profile: persistReducer(profilePersistConfig, profileReducer), | |||||
| chat: persistReducer(chatPersistConfig, chatReducer) | |||||
| }); | }); |
| OFFERS_CLEAR, | OFFERS_CLEAR, | ||||
| OFFERS_ERROR, | OFFERS_ERROR, | ||||
| OFFERS_NO_MORE, | OFFERS_NO_MORE, | ||||
| OFFERS_PINNED_ADD, | |||||
| OFFERS_PINNED_SET, | |||||
| OFFERS_SET, | OFFERS_SET, | ||||
| OFFER_ADD, | |||||
| } from "../../actions/offers/offersActionConstants"; | } from "../../actions/offers/offersActionConstants"; | ||||
| import createReducer from "../../utils/createReducer"; | import createReducer from "../../utils/createReducer"; | ||||
| const initialState = { | const initialState = { | ||||
| offers: [], | offers: [], | ||||
| pinnedOffers: [], | |||||
| error: "", | error: "", | ||||
| newOffer: "", | newOffer: "", | ||||
| noMoreOffers: false, | noMoreOffers: false, | ||||
| [OFFERS_CLEAR]: clearOffers, | [OFFERS_CLEAR]: clearOffers, | ||||
| [OFFERS_SET]: setOffers, | [OFFERS_SET]: setOffers, | ||||
| [OFFERS_ADD]: addOffers, | [OFFERS_ADD]: addOffers, | ||||
| [OFFER_ADD]: addOffer, | |||||
| [OFFERS_NO_MORE]: setNoMoreOffersStatus | |||||
| [OFFERS_NO_MORE]: setNoMoreOffersStatus, | |||||
| [OFFERS_PINNED_ADD]: addPinnedOffers, | |||||
| [OFFERS_PINNED_SET]: setPinnedOffers, | |||||
| }, | }, | ||||
| initialState | initialState | ||||
| ); | ); | ||||
| offers: [...state.offers, ...action.payload] | offers: [...state.offers, ...action.payload] | ||||
| } | } | ||||
| } | } | ||||
| function addOffer(state, action) { | |||||
| function setPinnedOffers(state, action) { | |||||
| return { | return { | ||||
| ...state, | ...state, | ||||
| offer: action.payload | |||||
| pinnedOffers: [...action.payload] | |||||
| } | |||||
| } | |||||
| function addPinnedOffers(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| pinnedOffers: [...state.pinnedOffers, ...action.payload] | |||||
| } | } | ||||
| } | } | ||||
| function setNoMoreOffersStatus(state, action) { | function setNoMoreOffersStatus(state, action) { |
| import { PROFILE_SET } from "../../actions/profile/profileActionConstants"; | |||||
| import createReducer from "../../utils/createReducer"; | |||||
| const initialState = { | |||||
| profile: {}, | |||||
| }; | |||||
| export default createReducer( | |||||
| { | |||||
| [PROFILE_SET]: setProfile, | |||||
| }, | |||||
| initialState | |||||
| ); | |||||
| function setProfile(state, action) { | |||||
| return { | |||||
| ...state, | |||||
| profile: action.payload, | |||||
| }; | |||||
| } |
| import { all, takeLatest, call, put } from "@redux-saga/core/effects"; | |||||
| import { attemptFetchChats } from "../../request/chatRequest"; | |||||
| import { CHAT_FETCH } from "../actions/chat/chatActionConstants"; | |||||
| import { setChats } from "../actions/chat/chatActions"; | |||||
| function* fetchChats(payload) { | |||||
| try { | |||||
| const data = yield call(attemptFetchChats, payload.payload); | |||||
| console.log(data.data); | |||||
| yield put(setChats(data.data)); | |||||
| } catch(e) { | |||||
| console.log(e); | |||||
| } | |||||
| } | |||||
| export default function* chatSaga() { | |||||
| yield all([ | |||||
| takeLatest(CHAT_FETCH, fetchChats) | |||||
| ]); | |||||
| } |
| function* forgotPassword({payload}) { | function* forgotPassword({payload}) { | ||||
| try { | try { | ||||
| console.log(payload) | |||||
| const data = yield call(forgotPasswordRequest, payload.email); | const data = yield call(forgotPasswordRequest, payload.email); | ||||
| if (data) { | if (data) { | ||||
| if (payload.handleResponseSuccess) { | if (payload.handleResponseSuccess) { |
| import { all } from 'redux-saga/effects'; | import { all } from 'redux-saga/effects'; | ||||
| import categoriesSaga from './categoriesSaga'; | import categoriesSaga from './categoriesSaga'; | ||||
| import chatSaga from './chatSaga'; | |||||
| import forgotPasswordSaga from './forgotPasswordSaga'; | import forgotPasswordSaga from './forgotPasswordSaga'; | ||||
| import locationsSaga from './locationsSaga'; | import locationsSaga from './locationsSaga'; | ||||
| import loginSaga from './loginSaga'; | import loginSaga from './loginSaga'; | ||||
| import offersSaga from './offersSaga'; | import offersSaga from './offersSaga'; | ||||
| import profileSaga from './profileSaga'; | |||||
| import registerSaga from './registerSaga'; | import registerSaga from './registerSaga'; | ||||
| export default function* rootSaga() { | export default function* rootSaga() { | ||||
| forgotPasswordSaga(), | forgotPasswordSaga(), | ||||
| offersSaga(), | offersSaga(), | ||||
| categoriesSaga(), | categoriesSaga(), | ||||
| locationsSaga() | |||||
| locationsSaga(), | |||||
| profileSaga(), | |||||
| chatSaga() | |||||
| ]); | ]); | ||||
| } | } |
| function* fetchLocations() { | function* fetchLocations() { | ||||
| const {data} = yield call(attemptFetchLocations) | const {data} = yield call(attemptFetchLocations) | ||||
| console.log(data); | |||||
| yield put(setLocations(data)); | yield put(setLocations(data)); | ||||
| } | } | ||||
| import { setUserAccessToken } from "../actions/user/userActions"; | import { setUserAccessToken } from "../actions/user/userActions"; | ||||
| import i18next from "i18next"; | import i18next from "i18next"; | ||||
| function* fetchUser({ payload }) { | |||||
| function* fetchLogin({ payload }) { | |||||
| try { | try { | ||||
| const { data } = yield call(attemptLogin, payload); | const { data } = yield call(attemptLogin, payload); | ||||
| if (data.token) { | if (data.token) { | ||||
| } | } | ||||
| } | } | ||||
| function* logoutUser() { | |||||
| function* logout() { | |||||
| try { | try { | ||||
| const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN); | ||||
| const user = jwt.decode(JwtToken); | const user = jwt.decode(JwtToken); | ||||
| export default function* loginSaga() { | export default function* loginSaga() { | ||||
| yield all([ | yield all([ | ||||
| takeLatest(LOGIN_USER_FETCH, fetchUser), | |||||
| takeLatest(LOGIN_USER_FETCH, fetchLogin), | |||||
| takeLatest(AUTHENTICATE_USER, authenticateUser), | takeLatest(AUTHENTICATE_USER, authenticateUser), | ||||
| takeLatest(LOGOUT_USER, logoutUser), | |||||
| takeLatest(LOGOUT_USER, logout), | |||||
| takeLatest(REFRESH_TOKEN, refreshUserToken) | takeLatest(REFRESH_TOKEN, refreshUserToken) | ||||
| ]); | ]); | ||||
| } | } |
| import { all, takeLatest, call, put } from "@redux-saga/core/effects"; | import { all, takeLatest, call, put } from "@redux-saga/core/effects"; | ||||
| import { | import { | ||||
| attemptAddOffer, | |||||
| attemptFetchMoreOffers, | attemptFetchMoreOffers, | ||||
| attemptFetchOffers, | attemptFetchOffers, | ||||
| } from "../../request/offersRequest"; | } from "../../request/offersRequest"; | ||||
| import { setQueryString } from "../actions/filters/filtersActions"; | |||||
| import { | import { | ||||
| OFFERS_FETCH, | OFFERS_FETCH, | ||||
| OFFERS_FETCH_MORE, | OFFERS_FETCH_MORE, | ||||
| OFFER_ADD, | |||||
| } from "../actions/offers/offersActionConstants"; | } from "../actions/offers/offersActionConstants"; | ||||
| import { | import { | ||||
| addOffers, | addOffers, | ||||
| addPinnedOffers, | |||||
| clearOffers, | clearOffers, | ||||
| setNoMoreOffersStatus, | setNoMoreOffersStatus, | ||||
| setOffers, | setOffers, | ||||
| setPinnedOffers, | |||||
| } from "../actions/offers/offersActions"; | } from "../actions/offers/offersActions"; | ||||
| function* fetchOffers(payload) { | function* fetchOffers(payload) { | ||||
| yield put(clearOffers()); | yield put(clearOffers()); | ||||
| yield put(setNoMoreOffersStatus(false)); | yield put(setNoMoreOffersStatus(false)); | ||||
| const data = yield call(attemptFetchOffers, payload.payload.queryString); | const data = yield call(attemptFetchOffers, payload.payload.queryString); | ||||
| if (data.data.items.length < 10) { | |||||
| if ( | |||||
| data.data.items.pinnedOffers.length + | |||||
| data.data.items.regularOffers.length < | |||||
| 10 || | |||||
| data.data.items.pinnedOffers.length + | |||||
| data.data.items.regularOffers.length > | |||||
| data.data.total | |||||
| ) { | |||||
| yield put(setNoMoreOffersStatus(true)); | yield put(setNoMoreOffersStatus(true)); | ||||
| } | } | ||||
| yield put(setOffers(data.data.items)); | |||||
| if (payload.payload.queryString) { | |||||
| yield put(setQueryString(payload.payload.queryString)); | |||||
| } | |||||
| yield put(setOffers(data.data.items.regularOffers)); | |||||
| yield put(setPinnedOffers(data.data.items.pinnedOffers)); | |||||
| } catch (e) { | } catch (e) { | ||||
| console.log(e); | |||||
| yield call(console.log, e); | |||||
| } | } | ||||
| } | } | ||||
| function* fetchMoreOffers(payload) { | function* fetchMoreOffers(payload) { | ||||
| payload.payload?.page, | payload.payload?.page, | ||||
| payload.payload?.queryString | payload.payload?.queryString | ||||
| ); | ); | ||||
| yield put(addOffers(data.data.items)); | |||||
| if (data.data.items.length < 10) { | |||||
| if (payload.payload.queryString) { | |||||
| yield put(setQueryString(payload.payload.queryString)); | |||||
| } | |||||
| console.log(data.data.items); | |||||
| yield put(addOffers(data.data.items.regularOffers)); | |||||
| yield put(addPinnedOffers(data.data.items.pinnedOffers)); | |||||
| if ( | |||||
| data.data.items.pinnedOffers + data.data.items.regularOffers < 10 || | |||||
| data.data.items.pinnedOffers.length + | |||||
| data.data.items.regularOffers.length > | |||||
| data.data.total | |||||
| ) { | |||||
| yield put(setNoMoreOffersStatus(true)); | yield put(setNoMoreOffersStatus(true)); | ||||
| } | } | ||||
| } catch (e) { | } catch (e) { | ||||
| } | } | ||||
| } | } | ||||
| function* createOffer(payload) { | |||||
| try { | |||||
| const data = yield call(attemptAddOffer, payload); | |||||
| console.log(data); | |||||
| } catch (e) { | |||||
| console.log(e); | |||||
| } | |||||
| } | |||||
| export default function* offersSaga() { | export default function* offersSaga() { | ||||
| yield all([ | yield all([ | ||||
| takeLatest(OFFERS_FETCH, fetchOffers), | takeLatest(OFFERS_FETCH, fetchOffers), | ||||
| takeLatest(OFFERS_FETCH_MORE, fetchMoreOffers), | takeLatest(OFFERS_FETCH_MORE, fetchMoreOffers), | ||||
| takeLatest(OFFER_ADD, createOffer), | |||||
| ]); | ]); | ||||
| } | } |
| import { all, call, put, takeLatest } from "@redux-saga/core/effects"; | |||||
| import { attemptFetchProfile } from "../../request/profileRequest"; | |||||
| import { PROFILE_FETCH } from "../actions/profile/profileActionConstants"; | |||||
| import { setProfile } from "../actions/profile/profileActions"; | |||||
| function* fetchProfile(payload) { | |||||
| try { | |||||
| console.log(payload); | |||||
| const data = yield call(attemptFetchProfile, payload.payload); | |||||
| console.log(data.data); | |||||
| if (data) yield put(setProfile(data.data)); | |||||
| } | |||||
| catch(e) { | |||||
| console.log(e); | |||||
| } | |||||
| } | |||||
| export default function* profileSaga() { | |||||
| yield all([ | |||||
| takeLatest(PROFILE_FETCH, fetchProfile) | |||||
| ]) | |||||
| } |
| import { createSelector } from "reselect"; | |||||
| const chatSelector = (state) => state.chat; | |||||
| export const selectLatestChats = createSelector( | |||||
| chatSelector, | |||||
| (state) => state.latestChats | |||||
| ) |
| filtersSelector, | filtersSelector, | ||||
| (state) => state.filters.isApplied | (state) => state.filters.isApplied | ||||
| ) | ) | ||||
| export const selectQueryString = createSelector( | |||||
| filtersSelector, | |||||
| (state) => state.filters.queryString | |||||
| ) |
| loginSelector, | loginSelector, | ||||
| (state) => state.token, | (state) => state.token, | ||||
| ); | ); | ||||
| export const selectUserId = createSelector( | |||||
| loginSelector, | |||||
| (state) => state.token.userId | |||||
| ) | |||||
| export const selectLoginError = createSelector( | export const selectLoginError = createSelector( | ||||
| loginSelector, | loginSelector, | ||||
| (state) => state.errorMessage, | (state) => state.errorMessage, |
| offersSelector, | offersSelector, | ||||
| (state) => state.noMoreOffers | (state) => state.noMoreOffers | ||||
| ) | ) | ||||
| export const selectPinnedOffers = createSelector( | |||||
| offersSelector, | |||||
| (state) => state.pinnedOffers | |||||
| ) |
| import { createSelector } from "reselect"; | |||||
| const profileSelector = (state) => state.profile.profile; | |||||
| export const selectProfileName = createSelector( | |||||
| profileSelector, | |||||
| (state) => state?.company?.name | |||||
| ) | |||||
| export const selectProfile = createSelector( | |||||
| profileSelector, | |||||
| (state) => state | |||||
| ) |
| export function authScopeStringGetHelper(key) { | export function authScopeStringGetHelper(key) { | ||||
| if (sessionStorage.getItem(SESSION_STORAGE_SCOPE)) { | if (sessionStorage.getItem(SESSION_STORAGE_SCOPE)) { | ||||
| console.log(sessionStorage.getItem(key)) | |||||
| return sessionStorage.getItem(key); | return sessionStorage.getItem(key); | ||||
| } | } | ||||
| console.log(localStorage.getItem(key)) | |||||
| return localStorage.getItem(key); | return localStorage.getItem(key); | ||||
| } | } |
| import { sortEnum } from "../../enums/sortEnum"; | |||||
| export const convertQueryString = (queryURL) => { | |||||
| const queryObject = new URLSearchParams(queryURL); | |||||
| const queryObjectToReturn = new URLSearchParams(queryURL); | |||||
| if (queryObject.has('_des_date')) { | |||||
| queryObjectToReturn.delete('_des_date'); | |||||
| if (queryObject.get('_des_date') === 'true') { | |||||
| queryObjectToReturn.append('sortBy', sortEnum.NEW.queryString); | |||||
| } else { | |||||
| queryObjectToReturn.append('sortBy', sortEnum.OLD.queryString); | |||||
| } | |||||
| } | |||||
| if (queryObject.has('_des_popular')) { | |||||
| queryObjectToReturn.delete('_des_popular'); | |||||
| queryObjectToReturn.append('sortBy', sortEnum.POPULAR.queryString); | |||||
| } | |||||
| return queryObjectToReturn.toString(); | |||||
| } |