Przeglądaj źródła

Fixed all bugs assigned to djordje

feature/587
Djordje Mitrovic 3 lat temu
rodzic
commit
782c77da1d
50 zmienionych plików z 560 dodań i 192 usunięć
  1. 5
    0
      package-lock.json
  2. 2
    1
      package.json
  3. 5
    0
      src/assets/images/svg/category-header.svg
  4. 4
    0
      src/assets/images/svg/half-logo.svg
  5. 3
    0
      src/assets/images/svg/like.svg
  6. 1
    10
      src/assets/images/svg/phone.svg
  7. 10
    0
      src/assets/images/svg/pin.svg
  8. 6
    0
      src/assets/images/svg/swaps.svg
  9. 3
    5
      src/components/Cards/ChatCard/ChatCard.js
  10. 22
    2
      src/components/Cards/ChatCard/ChatCommands/ChatCommands.js
  11. 5
    1
      src/components/Cards/ChatCard/ChatCommands/ChatCommands.styled.js
  12. 3
    3
      src/components/Cards/CreateOfferCard/FirstPart/FirstPartCreateOffer.js
  13. 2
    1
      src/components/Cards/FilterCard/Choser/SubcategoryChoser/SubcategoryChoser.js
  14. 16
    8
      src/components/Cards/FilterCard/FilterCard.js
  15. 10
    4
      src/components/Cards/FilterCard/FilterFooter/FilterFooter.js
  16. 8
    1
      src/components/Cards/FilterCard/FilterHeader/FilterHeader.js
  17. 13
    11
      src/components/Cards/OfferCard/OfferCard.js
  18. 43
    9
      src/components/Cards/OfferCard/OfferCard.styled.js
  19. 4
    3
      src/components/CreateReview/FirstStep/FirstStepCreateReview.js
  20. 1
    0
      src/components/CreateReview/FirstStep/FirstStepCreateReview.styled.js
  21. 24
    2
      src/components/DirectChat/DirectChatContent/DirectChatContentHeader/DirectChatContentHeader.js
  22. 2
    2
      src/components/Header/Header.js
  23. 5
    1
      src/components/Header/Header.styled.js
  24. 2
    2
      src/components/IconButton/IconButton.js
  25. 25
    15
      src/components/MarketPlace/Header/Header.js
  26. 7
    2
      src/components/MarketPlace/Header/Header.styled.js
  27. 2
    0
      src/components/MarketPlace/Offers/Offers.js
  28. 2
    2
      src/components/MarketPlace/Offers/Offers.styled.js
  29. 0
    1
      src/components/Popovers/HeaderPopover/HeaderPopover.styled.js
  30. 24
    0
      src/components/Popovers/PhonePopover/PhonePopover.js
  31. 44
    0
      src/components/Popovers/PhonePopover/PhonePopover.styled.js
  32. 19
    2
      src/components/Popovers/PopoverComponent.js
  33. 21
    0
      src/components/Profile/ProfileOffers/NoProfileOffers.js/NoProfileOffers.js
  34. 35
    0
      src/components/Profile/ProfileOffers/NoProfileOffers.js/NoProfileOffers.styled.js
  35. 70
    45
      src/components/Profile/ProfileOffers/ProfileOffers.js
  36. 10
    10
      src/components/ProfileCard/EditProfile/EditProfile.js
  37. 16
    12
      src/components/ProfileCard/ProfileContact/ProfileContact.js
  38. 3
    3
      src/components/UserReviews/NoReviews/NoReviews.js
  39. 1
    1
      src/components/UserReviews/UserReviews.styled.js
  40. 19
    0
      src/hooks/useIsMobile.js
  41. 6
    0
      src/hooks/useOffers/useMyOffers.js
  42. 4
    0
      src/i18n/resources/rs.js
  43. 1
    1
      src/pages/HomePage/HomePage.styled.js
  44. 20
    10
      src/pages/RegisterPages/Register/FirstPart/FirstPartOfRegistration.js
  45. 2
    1
      src/pages/RegisterPages/Register/Register.js
  46. 16
    14
      src/pages/RegisterPages/Register/Register.styled.js
  47. 0
    1
      src/request/index.js
  48. 8
    2
      src/store/saga/profileSaga.js
  49. 1
    0
      src/util/helpers/queryHelpers.js
  50. 5
    4
      src/validations/registerValidations/firstPartValidation.js

+ 5
- 0
package-lock.json Wyświetl plik

@@ -19118,6 +19118,11 @@
}
}
}
},
"yup-password": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/yup-password/-/yup-password-0.2.2.tgz",
"integrity": "sha512-2PHfqGWtbXg4OfDV7VKFIb3hyEaYgTYpEORnFqgGAYqzENWmGzWMoeGvJg2Ohmq6maTRxhJzLZpNTITrqlZTrA=="
}
}
}

+ 2
- 1
package.json Wyświetl plik

@@ -45,7 +45,8 @@
"socket.io-client": "^4.5.1",
"styled-components": "^5.3.5",
"web-vitals": "^1.1.2",
"yup": "^0.32.9"
"yup": "^0.32.9",
"yup-password": "^0.2.2"
},
"scripts": {
"start": "react-scripts start",

+ 5
- 0
src/assets/images/svg/category-header.svg Wyświetl plik

@@ -0,0 +1,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.99984 1.66675L1.6665 5.83341L9.99984 10.0001L18.3332 5.83341L9.99984 1.66675Z" stroke="#4D4D4D" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.6665 14.1667L9.99984 18.3334L18.3332 14.1667" stroke="#4D4D4D" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.6665 10L9.99984 14.1667L18.3332 10" stroke="#4D4D4D" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

+ 4
- 0
src/assets/images/svg/half-logo.svg Wyświetl plik

@@ -0,0 +1,4 @@
<svg width="85" height="84" viewBox="0 0 85 84" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="34.8508" cy="19.0459" r="10.5693" transform="rotate(45 34.8508 19.0459)" fill="#FEB005"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M51.5556 12.6063C48.8541 9.9048 44.4742 9.90481 41.7728 12.6063L27.6188 26.7602C27.6189 26.7604 27.6191 26.7605 27.6192 26.7606C31.7468 30.8882 31.7468 37.5803 27.6192 41.7079C23.5128 45.8143 16.8681 45.8354 12.7356 41.7711C10.7896 44.4744 11.0325 48.266 13.4642 50.6977L41.7727 79.0063C44.4742 81.7077 48.8541 81.7077 51.5556 79.0063L79.8642 50.6977C82.5656 47.9962 82.5656 43.6163 79.8642 40.9149L51.5556 12.6063Z" fill="#FEB005"/>
</svg>

+ 3
- 0
src/assets/images/svg/like.svg Wyświetl plik

@@ -0,0 +1,3 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.25 16.5H3C2.60218 16.5 2.22064 16.342 1.93934 16.0607C1.65804 15.7794 1.5 15.3978 1.5 15V9.75C1.5 9.35218 1.65804 8.97064 1.93934 8.68934C2.22064 8.40804 2.60218 8.25 3 8.25H5.25M10.5 6.75V3.75C10.5 3.15326 10.2629 2.58097 9.84099 2.15901C9.41903 1.73705 8.84674 1.5 8.25 1.5L5.25 8.25V16.5H13.71C14.0717 16.5041 14.4228 16.3773 14.6984 16.143C14.9741 15.9087 15.1558 15.5827 15.21 15.225L16.245 8.475C16.2776 8.26002 16.2631 8.04051 16.2025 7.83169C16.1419 7.62287 16.0366 7.42972 15.8939 7.26564C15.7512 7.10155 15.5746 6.97045 15.3762 6.88141C15.1778 6.79238 14.9624 6.74754 14.745 6.75H10.5Z" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

+ 1
- 10
src/assets/images/svg/phone.svg Wyświetl plik

@@ -1,12 +1,3 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_789_9087)">
<path d="M14.25 0.75L17.25 3.75L14.25 6.75" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M11.25 3.75H17.25" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M16.5001 12.6901V14.9401C16.5009 15.1489 16.4581 15.3557 16.3745 15.5471C16.2908 15.7385 16.168 15.9103 16.0141 16.0515C15.8602 16.1927 15.6785 16.3002 15.4806 16.3671C15.2828 16.434 15.0731 16.4589 14.8651 16.4401C12.5572 16.1893 10.3403 15.4007 8.39257 14.1376C6.58044 12.9861 5.04407 11.4497 3.89257 9.63757C2.62506 7.68098 1.83625 5.45332 1.59007 3.13507C1.57133 2.92767 1.59598 2.71864 1.66245 2.52129C1.72892 2.32394 1.83575 2.14259 1.97615 1.98879C2.11654 1.83499 2.28743 1.7121 2.47792 1.62796C2.6684 1.54382 2.87433 1.50027 3.08257 1.50007H5.33257C5.69655 1.49649 6.04942 1.62538 6.32539 1.86272C6.60137 2.10006 6.78163 2.42966 6.83257 2.79007C6.92754 3.51012 7.10366 4.21712 7.35757 4.89757C7.45848 5.16602 7.48032 5.45776 7.4205 5.73823C7.36069 6.01871 7.22172 6.27616 7.02007 6.48007L6.06757 7.43257C7.13524 9.31023 8.68991 10.8649 10.5676 11.9326L11.5201 10.9801C11.724 10.7784 11.9814 10.6395 12.2619 10.5796C12.5424 10.5198 12.8341 10.5417 13.1026 10.6426C13.783 10.8965 14.49 11.0726 15.2101 11.1676C15.5744 11.219 15.9071 11.4025 16.145 11.6832C16.3828 11.9639 16.5092 12.3223 16.5001 12.6901Z" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_789_9087">
<rect width="18" height="18" fill="white"/>
</clipPath>
</defs>
<path d="M16.4999 12.6901V14.9401C16.5008 15.1489 16.458 15.3557 16.3743 15.5471C16.2907 15.7385 16.1679 15.9103 16.014 16.0515C15.8601 16.1927 15.6784 16.3002 15.4805 16.3671C15.2826 16.434 15.073 16.4589 14.8649 16.4401C12.5571 16.1893 10.3402 15.4007 8.39245 14.1376C6.58032 12.9861 5.04395 11.4497 3.89245 9.63757C2.62493 7.68098 1.83613 5.45332 1.58995 3.13507C1.57121 2.92767 1.59586 2.71864 1.66233 2.52129C1.72879 2.32394 1.83563 2.14259 1.97602 1.98879C2.11642 1.83499 2.2873 1.7121 2.47779 1.62796C2.66828 1.54382 2.87421 1.50027 3.08245 1.50007H5.33245C5.69643 1.49649 6.04929 1.62538 6.32527 1.86272C6.60125 2.10006 6.78151 2.42966 6.83245 2.79007C6.92742 3.51012 7.10354 4.21712 7.35745 4.89757C7.45836 5.16602 7.4802 5.45776 7.42038 5.73823C7.36056 6.01871 7.2216 6.27616 7.01995 6.48007L6.06745 7.43257C7.13512 9.31023 8.68979 10.8649 10.5675 11.9326L11.5199 10.9801C11.7239 10.7784 11.9813 10.6395 12.2618 10.5796C12.5423 10.5198 12.834 10.5417 13.1024 10.6426C13.7829 10.8965 14.4899 11.0726 15.21 11.1676C15.5743 11.219 15.907 11.4025 16.1448 11.6832C16.3827 11.9639 16.5091 12.3223 16.4999 12.6901Z" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

+ 10
- 0
src/assets/images/svg/pin.svg Wyświetl plik

@@ -0,0 +1,10 @@
<svg width="22" height="23" viewBox="0 0 22 23" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1316_10558)">
<path d="M9.81609 1.53679C10.1267 0.998802 10.8149 0.814402 11.3529 1.12501L19.1471 5.62501C19.686 5.93614 19.8695 6.6238 19.5589 7.16179C19.2483 7.69977 18.561 7.8847 18.0221 7.57356L17.1239 7.05501L14.8659 11.7675C15.6335 13.0185 15.9281 14.5404 15.6218 16.0482L15.5995 16.1572C15.5264 16.5087 15.2604 16.7936 14.9319 16.9408C14.6259 17.1052 14.2475 17.0856 13.9339 16.9046L4.19109 11.2796C3.8778 11.0987 3.66982 10.7797 3.63449 10.4183C3.59729 10.0599 3.73729 9.7023 4.00684 9.46415L4.09008 9.39042C5.24052 8.36994 6.70729 7.86497 8.17508 7.90456L11.1272 3.59282L10.2279 3.07356C9.68988 2.76296 9.50548 2.07477 9.81609 1.53679ZM9.47426 15.6289L7.78676 18.5517C7.47563 19.0906 6.78888 19.2746 6.24998 18.9635C5.71108 18.6523 5.52707 17.9656 5.8382 17.4267L7.5257 14.5039L9.47426 15.6289Z" fill="#FEB005"/>
</g>
<defs>
<clipPath id="clip0_1316_10558">
<rect width="13.5" height="18" fill="white" transform="translate(9.4043) rotate(30)"/>
</clipPath>
</defs>
</svg>

+ 6
- 0
src/assets/images/svg/swaps.svg Wyświetl plik

@@ -0,0 +1,6 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.66754 1.08737L15.6675 4.08737C15.9174 4.21155 16.1278 4.40299 16.2748 4.64015C16.4219 4.87732 16.4999 5.1508 16.5 5.42987V12.5774C16.4999 12.8564 16.4219 13.1299 16.2748 13.3671C16.1278 13.6043 15.9174 13.7957 15.6675 13.9199L9.66754 16.9199C9.45914 17.0241 9.22932 17.0784 8.99629 17.0784C8.76326 17.0784 8.53343 17.0241 8.32504 16.9199L2.32504 13.9199C2.07538 13.7941 1.86585 13.601 1.72008 13.3625C1.5743 13.1239 1.49809 12.8494 1.50004 12.5699V5.42987C1.50018 5.1508 1.57818 4.87732 1.72525 4.64015C1.87231 4.40299 2.08263 4.21155 2.33254 4.08737L8.33254 1.08737C8.53995 0.9843 8.76842 0.930664 9.00004 0.930664C9.23165 0.930664 9.46012 0.9843 9.66754 1.08737V1.08737Z" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M1.74023 4.62012L9.00023 8.25012L16.2602 4.62012" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M9 17.07V8.25" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M5.25 2.625L12.75 6.375" stroke="#5A3984" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

+ 3
- 5
src/components/Cards/ChatCard/ChatCard.js Wyświetl plik

@@ -11,15 +11,15 @@ import {
Line,
} from "./ChatCard.styled";
import { useHistory } from "react-router-dom";
import useScreenDimensions from "../../../hooks/useScreenDimensions";
import LittleOfferDetails from "./LittleOfferDetails/LittleOfferDetails";
import MobileOfferDetails from "./MobileOfferDetails/MobileOfferDetails";
import OfferLocation from "./OfferLocation/OfferLocation";
import ChatCommands from "./ChatCommands/ChatCommands";
import useIsMobile from "../../../hooks/useIsMobile";

const ChatCard = (props) => {
const history = useHistory();
const dimensions = useScreenDimensions();
const { isMobile } = useIsMobile();

const chat = useMemo(() => {
return props.chat;
@@ -36,9 +36,7 @@ const ChatCard = (props) => {
};
return (
<ChatCardContainer
onClick={
dimensions.width < 600 ? () => routeToItem(chat?.chat?._id) : () => {}
}
onClick={isMobile ? () => routeToItem(chat?.chat?._id) : () => {}}
>
<Col>
<UserImgWrapper>

+ 22
- 2
src/components/Cards/ChatCard/ChatCommands/ChatCommands.js Wyświetl plik

@@ -1,20 +1,30 @@
import React from "react";
import React, { useState } from "react";
import PropTypes from "prop-types";
import {
CheckButton,
Commands,
PhoneIcon,
PhoneIconContainer,
Popover,
} from "./ChatCommands.styled";
import selectedTheme from "../../../../themes";
import { useTranslation } from "react-i18next";
import PhonePopover from "../../../Popovers/PhonePopover/PhonePopover";

const ChatCommands = (props) => {
const { t } = useTranslation();
const [showPhonePopover, setShowPhonePopover] = useState(false);
const [phonePopoverAnchorEl, setPhonePopoverAnchorEl] = useState(null);

return (
<Commands>
<PhoneIconContainer>
<PhoneIconContainer
onClick={(event) => {
console.log(event);
setShowPhonePopover(true);
setPhonePopoverAnchorEl(event.currentTarget);
}}
>
<PhoneIcon />
</PhoneIconContainer>
<CheckButton
@@ -26,6 +36,16 @@ const ChatCommands = (props) => {
>
{t("messages.seeChats")}
</CheckButton>
<Popover
anchorEl={phonePopoverAnchorEl}
open={showPhonePopover}
anchorRight
onClose={() => {
setShowPhonePopover(false);
setPhonePopoverAnchorEl(null);
}}
content={<PhonePopover />}
/>
</Commands>
);
};

+ 5
- 1
src/components/Cards/ChatCard/ChatCommands/ChatCommands.styled.js Wyświetl plik

@@ -4,6 +4,7 @@ import { ReactComponent as Phone } from "../../../../assets/images/svg/phone.svg
import selectedTheme from "../../../../themes";
import { PrimaryButton } from "../../../Buttons/PrimaryButton/PrimaryButton";
import IconButton from "../../../IconButton/IconButton";
import PopoverComponent from "../../../Popovers/PopoverComponent";


export const Commands = styled(Box)`
@@ -72,4 +73,7 @@ export const CheckButton = styled(PrimaryButton)`
display: none;
}
transition: 0.2s all;
`;
`;
export const Popover = styled(PopoverComponent)`
`

+ 3
- 3
src/components/Cards/CreateOfferCard/FirstPart/FirstPartCreateOffer.js Wyświetl plik

@@ -14,13 +14,13 @@ import selectedTheme from "../../../../themes";
import { useTranslation } from "react-i18next";
import { SelectField } from "../CreateOffer.styled";
import { useSelector } from "react-redux";
import useScreenDimensions from "../../../../hooks/useScreenDimensions";
import useIsMobile from "../../../../hooks/useIsMobile";

const FirstPartCreateOffer = (props) => {
const [subcat, setSubcat] = useState([]);
const locations = useSelector((state) => state.locations.locations);
const categories = useSelector((state) => state.categories.categories);
const dimensions = useScreenDimensions();
const { isMobile } = useIsMobile();

const { t } = useTranslation();

@@ -103,7 +103,7 @@ const FirstPartCreateOffer = (props) => {
/>

<FieldLabel leftText={t("offer.productDescription")} />
{dimensions.width > 600 ? (
{!isMobile ? (
<DescriptionField
name="description"
placeholder={t("offer.description")}

+ 2
- 1
src/components/Cards/FilterCard/Choser/SubcategoryChoser/SubcategoryChoser.js Wyświetl plik

@@ -33,7 +33,7 @@ const SubcategoryChoser = forwardRef((props, ref) => {
}));

useEffect(() => {
if (props.queryStringHook.isInitiallyLoaded) {
if (props?.queryStringHook?.isInitiallyLoaded || props.isMyOffers) {
if (
!filters.category.selectedCategoryLocally ||
filters.category.selectedCategoryLocally?._id === 0
@@ -90,6 +90,7 @@ SubcategoryChoser.propTypes = {
filters: PropTypes.any,
categoryOpened: PropTypes.bool,
queryStringHook: PropTypes.any,
isMyOffers: PropTypes.bool,
};

export default SubcategoryChoser;

+ 16
- 8
src/components/Cards/FilterCard/FilterCard.js Wyświetl plik

@@ -19,7 +19,7 @@ const FilterCard = (props) => {
categoryRef.current.closeSection();
subcategoryRef.current.closeSection();
locationRef.current.closeSection();
}
};
return (
<FilterCardContainer
filtersOpened={props.filtersOpened}
@@ -33,23 +33,31 @@ const FilterCard = (props) => {
{/* Header title for my offers */}
{props.myOffers && <HeaderBack />}

<FilterHeader filters={offers} closeAllSections={closeAllSections} />
<FilterHeader
filters={offers}
closeAllSections={closeAllSections}
isMyOffers={props.myOffers}
toggleFilters={props.toggleFilters}
/>

<ContentContainer>
{/* Categories */}
<CategoryChoser filters={filters} ref={categoryRef} />

{/* Subcategories */}
<SubcategoryChoser filters={filters} queryStringHook={offers.queryStringHook} ref={subcategoryRef} categoryOpened={categoryRef.current?.isOpened} />
<SubcategoryChoser
filters={filters}
queryStringHook={offers.queryStringHook}
ref={subcategoryRef}
categoryOpened={categoryRef.current?.isOpened}
isMyOffers={props.myOffers}
/>

{/* Locations */}
<LocationChoser filters={filters} ref={locationRef}/>
<LocationChoser filters={filters} ref={locationRef} />
</ContentContainer>

<FilterFooter
toggleFilters={props.toggleFilters}
filters={offers}
/>
<FilterFooter toggleFilters={props.toggleFilters} filters={offers} />
</FilterCardContainer>
);
};

+ 10
- 4
src/components/Cards/FilterCard/FilterFooter/FilterFooter.js Wyświetl plik

@@ -4,18 +4,24 @@ import { FilterFooterContainer } from "./FilterFooter.styled";
import selectedTheme from "../../../../themes";
import { PrimaryButton } from "../../../Buttons/PrimaryButton/PrimaryButton";
import { useTranslation } from "react-i18next";
import useScreenDimensions from "../../../../hooks/useScreenDimensions";
import useSearch from "../../../../hooks/useOffers/useSearch";
import useIsMobile from "../../../../hooks/useIsMobile";

const FilterFooter = (props) => {
const { t } = useTranslation();
console.log(useIsMobile);
console.log(useSearch);
console.log(useTranslation);
const isMobile = useIsMobile;
console.log(isMobile);
const filters = props.filters;
const screenDimensions = useScreenDimensions();
const handleFilters = () => {
filters.apply();
props.toggleFilters();
};
return (
<FilterFooterContainer responsiveOpen={screenDimensions.width < 600}>
{screenDimensions.width < 600 && (
<FilterFooterContainer responsiveOpen={isMobile}>
{isMobile && (
<PrimaryButton
variant="outlined"
fullWidth

+ 8
- 1
src/components/Cards/FilterCard/FilterHeader/FilterHeader.js Wyświetl plik

@@ -8,7 +8,12 @@ const FilterHeader = (props) => {
const filters = props.filters;
const { t } = useTranslation();
const clearFilters = () => {
filters.clearFiltersAndApply();
if (props.isMyOffers) {
filters.clear();
} else {
filters.clearFiltersAndApply();
}
props.toggleFilters();
props.closeAllSections();
};
return (
@@ -25,6 +30,8 @@ FilterHeader.propTypes = {
children: PropTypes.node,
filters: PropTypes.any,
closeAllSections: PropTypes.func,
isMyOffers: PropTypes.bool,
toggleFilters: PropTypes.func,
};

export default FilterHeader;

+ 13
- 11
src/components/Cards/OfferCard/OfferCard.js Wyświetl plik

@@ -25,10 +25,11 @@ import {
OfferTitle,
OfferTitleAboveImage,
OfferViews,
PinIcon,
RemoveIcon,
RemoveIconContainer,
StarIcon,
StarIconContainer,
LikeIcon,
LikeIconContainer,
} from "./OfferCard.styled";
import DeleteOffer from "./DeleteOffer/DeleteOffer";
import { ReactComponent as Category } from "../../../assets/images/svg/category.svg";
@@ -103,12 +104,12 @@ const OfferCard = (props) => {
></OfferImage>
</OfferImageContainer>
<OfferInfo vertical={props.vertical}>
<OfferTitle
vertical={props.vertical}
onClick={() => routeToItem(props?.offer?._id)}
>
{props?.offer?.name}
</OfferTitle>
<OfferTitle
vertical={props.vertical}
onClick={() => routeToItem(props?.offer?._id)}
>
{props?.offer?.name}
</OfferTitle>
<OfferAuthor>
<OfferAuthorName vertical={props.vertical}>
{props?.offer?.user?.company?.name}
@@ -178,12 +179,12 @@ const OfferCard = (props) => {
</EditIconContainer>
</>
) : props.aboveChat ? (
<StarIconContainer
<LikeIconContainer
disabled={props.disabledReviews}
onClick={makeReview}
>
<StarIcon disabled={props.disabledReviews} />
</StarIconContainer>
<LikeIcon disabled={props.disabledReviews} />
</LikeIconContainer>
) : (
<MessageIcon
showMessageIcon={showMessageIcon}
@@ -193,6 +194,7 @@ const OfferCard = (props) => {
<Message />
</MessageIcon>
)}
{props?.offer?.pinned && <PinIcon isMyOffer={props.isMyOffer} />}
</OfferFlexContainer>
</OfferCardContainer>
{deleteOfferModal && (

+ 43
- 9
src/components/Cards/OfferCard/OfferCard.styled.js Wyświetl plik

@@ -7,7 +7,8 @@ import { Icon } from "../../Icon/Icon";
import { ReactComponent as Eye } from "../../../assets/images/svg/eye-striked.svg";
import { ReactComponent as Remove } from "../../../assets/images/svg/trash.svg";
import { ReactComponent as Edit } from "../../../assets/images/svg/edit.svg";
import { ReactComponent as Star } from "../../../assets/images/svg/star.svg";
import { ReactComponent as Like } from "../../../assets/images/svg/like.svg";
import { ReactComponent as Pin } from "../../../assets/images/svg/pin.svg";

export const OfferCardContainer = styled(Container)`
display: ${(props) => (props.skeleton ? "none" : "flex")};
@@ -28,7 +29,7 @@ export const OfferCardContainer = styled(Container)`
height: 180px;
position: relative;
@media (max-width: 550px) {
height: 184px;
height: 194px;
padding: 18px;
padding-top: 12px;
${(props) =>
@@ -91,6 +92,13 @@ export const OfferTitle = styled(Typography)`
font-size: 24px;
width: calc(100% - 120px);
cursor: pointer;
overflow: hidden;
line-height: 33px;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
max-height: 33px;
margin-bottom: 28px;
@media (max-width: 550px) {
width: 100%;
font-size: 18px;
@@ -305,10 +313,17 @@ export const OfferImageContainer = styled(Box)`
}
`;
export const OfferTitleAboveImage = styled(OfferTitle)`
padding-bottom: 12px;
padding-bottom: 18px;
padding-top: 5px;
padding-left: 1px;
display: block;
width: 60%;
max-width: 60%;
height: 40px;
line-height: 20px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
${(props) => props.vertical && `display: none;`}
@media (min-width: 551px) {
display: none;
@@ -330,8 +345,8 @@ export const RemoveIconContainer = styled(MessageIcon)`
@media screen and (max-width: 600px) {
position: absolute;
display: block;
right: 20px;
top: 75%;
right: 16px;
top: 16px;
}
`;
export const RemoveIcon = styled(Remove)``;
@@ -343,12 +358,12 @@ export const EditIconContainer = styled(MessageIcon)`
@media screen and (max-width: 600px) {
position: absolute;
display: block;
right: 20px;
top: 60%;
right: 55px;
top: 16px;
}
`;
export const EditIcon = styled(Edit)``;
export const StarIconContainer = styled(MessageIcon)`
export const LikeIconContainer = styled(MessageIcon)`
display: block;
opacity: ${(props) => (props.disabled ? "0.4" : "1")};
${(props) =>
@@ -360,7 +375,7 @@ export const StarIconContainer = styled(MessageIcon)`
}
`}
`;
export const StarIcon = styled(Star)`
export const LikeIcon = styled(Like)`
& path {
stroke: ${(props) =>
props.disabled
@@ -368,3 +383,22 @@ export const StarIcon = styled(Star)`
: selectedTheme.primaryPurple};
}
`;
export const PinIcon = styled(Pin)`
position: absolute;
top: 20px;
right: 68px;
@media (max-width: 600px) {
top: 20px;
right: 55px;
}
${(props) =>
props.isMyOffer &&
`
right: 134px;
top: 26px;
@media (max-width: 600px) {
top: 20px;
right: 94px;
}
`}
`;

+ 4
- 3
src/components/CreateReview/FirstStep/FirstStepCreateReview.js Wyświetl plik

@@ -18,12 +18,12 @@ import { NextButton } from "../CreateReview.styled";
import selectedTheme from "../../../themes";
import { useFormik } from "formik";
import * as Yup from "yup";
import useScreenDimensions from "../../../hooks/useScreenDimensions";
import useIsMobile from "../../../hooks/useIsMobile";

const FirstStepCreateReview = (props) => {
const offer = props.offer;
const interlocutor = props.interlocutor;
const dimensions = useScreenDimensions();
const { isMobile } = useIsMobile();
const { t } = useTranslation();
const handleSubmit = (values) => {
props.goToNextStep(values);
@@ -94,6 +94,7 @@ const FirstStepCreateReview = (props) => {
<FieldLabel leftText={t("reviews.hasExchangeSucceed").toUpperCase()} />
<SelectField
defaultValue={formik.values.exchangeSucceed}
exchange
onChange={(event) =>
formik.setFieldValue("exchangeSucceed", event.target.value)
}
@@ -119,7 +120,7 @@ const FirstStepCreateReview = (props) => {
value={formik.values.comment}
name="comment"
onChange={formik.handleChange}
height={dimensions.width < 600 ? "64px" : "100px"}
height={isMobile ? "64px" : "100px"}
/>

<NextButton

+ 1
- 0
src/components/CreateReview/FirstStep/FirstStepCreateReview.styled.js Wyświetl plik

@@ -70,6 +70,7 @@ export const SelectField = styled(Select)`
margin-bottom: 18px;
height: 48px;
text-align: left;
${props => props.exchange && `background-color: ${selectedTheme.backgroundSponsoredColor};`}
@media (max-width: 600px) {
height: 33px;
font-size: 14px;

+ 24
- 2
src/components/DirectChat/DirectChatContent/DirectChatContentHeader/DirectChatContentHeader.js Wyświetl plik

@@ -1,4 +1,4 @@
import React from "react";
import React, { useState } from "react";
import PropTypes from "prop-types";
import {
DirectChatContentHeaderContainer,
@@ -12,8 +12,20 @@ import {
ProfileLocationText,
ProfileName,
} from "./DirectChatContentHeader.styled";
import PopoverComponent from "../../../Popovers/PopoverComponent";
import PhonePopover from "../../../Popovers/PhonePopover/PhonePopover";

const DirectChatContentHeader = (props) => {
const [showPhonePopover, setShowPhonePopover] = useState(false);
const [phonePopoverAnchorEl, setPhonePopoverAnchorEl] = useState(null);

const togglePhonePopover = (event) => {
console.log(event);
setShowPhonePopover(true);
setPhonePopoverAnchorEl(event.currentTarget);
}

return (
<DirectChatContentHeaderContainer>
<DirectChatContentHeaderFlexContainer>
@@ -29,10 +41,20 @@ const DirectChatContentHeader = (props) => {
</ProfileDetails>
</DirectChatContentHeaderFlexContainer>
<DirectChatContentHeaderFlexContainer>
<PhoneIconContainer>
<PhoneIconContainer onClick={togglePhonePopover}>
<PhoneIcon />
</PhoneIconContainer>
</DirectChatContentHeaderFlexContainer>
<PopoverComponent
anchorEl={phonePopoverAnchorEl}
open={showPhonePopover}
anchorRight
onClose={() => {
setShowPhonePopover(false);
setPhonePopoverAnchorEl(null);
}}
content={<PhonePopover />}
/>
</DirectChatContentHeaderContainer>
);
};

+ 2
- 2
src/components/Header/Header.js Wyświetl plik

@@ -12,6 +12,7 @@ import {
SearchIcon,
SearchInput,
SearchInputMobile,
SwapsIcon,
ToggleDrawerButton,
ToolsButtonsContainer,
ToolsContainer,
@@ -23,7 +24,6 @@ import { AppBar, Badge, Toolbar, useMediaQuery } from "@mui/material";
import { useTheme } from "@mui/system";
import MenuOutlinedIcon from "@mui/icons-material/MenuOutlined";
import MailIcon from "@mui/icons-material/EmailOutlined";
import Autorenew from "@mui/icons-material/Autorenew";
import AccountCircle from "@mui/icons-material/PersonOutlineOutlined";
import Drawer from "../MUI/DrawerComponent";
import PopoverComponent from "../Popovers/PopoverComponent";
@@ -277,7 +277,7 @@ const Header = () => {
color: selectedTheme.primaryPurple,
}}
>
<Autorenew />
<SwapsIcon />
</IconButton>
<IconButton
onClick={(e) => {

+ 5
- 1
src/components/Header/Header.styled.js Wyświetl plik

@@ -3,11 +3,12 @@ import styled from "styled-components";
import { PrimaryButton } from "../Buttons/PrimaryButton/PrimaryButton";
import { TextField } from "../TextFields/TextField/TextField";
import { ReactComponent as Search } from "../../assets/images/svg/magnifying-glass.svg";
import { ReactComponent as Swaps } from "../../assets/images/svg/swaps.svg";
import selectedTheme from "../../themes";
import { Icon } from "../Icon/Icon";

export const SearchInput = styled(TextField)`
background-color: #f4f4f4;
background-color: ${selectedTheme.primaryBackgroundColor};
width: 45%;
flex: 3;
max-width: 520px;
@@ -194,3 +195,6 @@ export const SearchInputMobile = styled(SearchInput)`
}
`;
export const HeaderContainer = styled(Box)``;
export const SwapsIcon = styled(Swaps)`

`

+ 2
- 2
src/components/IconButton/IconButton.js Wyświetl plik

@@ -4,10 +4,10 @@ import PropType from 'prop-types';
const IconButton = ({ children, onClick, className }) => {
const buttonRef = useRef(null);

function handleClick() {
function handleClick(event) {
buttonRef.current.blur();
if (typeof onClick === 'function') {
onClick();
onClick(event);
}
}


+ 25
- 15
src/components/MarketPlace/Header/Header.js Wyświetl plik

@@ -1,6 +1,7 @@
import React from "react";
import PropTypes from "prop-types";
import {
CategoryHeaderIcon,
HeaderAltLocation,
HeaderButton,
HeaderButtons,
@@ -56,22 +57,31 @@ const Header = (props) => {
<HeaderContainer skeleton={props.skeleton}>
{/* Setting appropriate header title if page is market place or my offers */}
<Tooltip title={headerString}>
{!props.myOffers ? (
headerString === "Sve kategorije" &&
(sorting.selectedSortOption === sortEnum.INITIAL ||
sorting.selectedSortOption === sortEnum.NEW) ? (
<React.Fragment>
<HeaderLocation initial>{headerString}</HeaderLocation>
<HeaderAltLocation>{t("header.newOffers")}</HeaderAltLocation>
</React.Fragment>
<>
{!props.myOffers ? (
<>
<CategoryHeaderIcon />
{headerString === "Sve kategorije" &&
(sorting.selectedSortOption === sortEnum.INITIAL ||
sorting.selectedSortOption === sortEnum.NEW) ? (
<React.Fragment>
<HeaderLocation initial>{headerString}</HeaderLocation>
<HeaderAltLocation>
{t("header.newOffers")}
</HeaderAltLocation>
</React.Fragment>
) : (
<>
<HeaderLocation>{headerString}</HeaderLocation>
</>
)}
</>
) : (
<HeaderLocation>{headerString}</HeaderLocation>
)
) : (
<MySwapsTitle>
<RefreshIcon /> {t("header.myOffers")}
</MySwapsTitle>
)}
<MySwapsTitle>
<RefreshIcon /> {t("header.myOffers")}
</MySwapsTitle>
)}
</>
</Tooltip>
{/* ^^^^^^ */}


+ 7
- 2
src/components/MarketPlace/Header/Header.styled.js Wyświetl plik

@@ -4,7 +4,8 @@ import selectedTheme from "../../../themes";
import { IconButton } from "../../Buttons/IconButton/IconButton";
import Option from "../../Select/Option/Option";
import Select from "../../Select/Select";
import { ReactComponent as Refresh } from "../../../assets/images/svg/refresh.svg";
import { ReactComponent as Swaps } from "../../../assets/images/svg/swaps.svg";
import { ReactComponent as CategoryHeader } from "../../../assets/images/svg/category-header.svg";

export const HeaderContainer = styled(Box)`
margin-top: 20px;
@@ -19,6 +20,7 @@ export const HeaderLocation = styled(Box)`
line-height: 22px;
font-size: 16px;
flex: 2;
margin-left: 9px;
max-width: ${(props) => (props.initial ? "fit-content" : "50%")};
white-space: nowrap;
overflow: hidden;
@@ -54,6 +56,7 @@ export const HeaderSelect = styled(Select)`
font-weight: 400;
position: relative;
left: -5px;
background-color: white;
& div:first-child {
padding-left: 8px;
}
@@ -94,7 +97,7 @@ export const HeaderAltLocation = styled(Typography)`
display: none;
}
`;
export const RefreshIcon = styled(Refresh)`
export const RefreshIcon = styled(Swaps)`
width: 18px;
height: 18px;
position: relative;
@@ -111,3 +114,5 @@ export const MySwapsTitle = styled(Typography)`
position: relative;
left: 9px;
`;
export const CategoryHeaderIcon = styled(CategoryHeader)`
`

+ 2
- 0
src/components/MarketPlace/Offers/Offers.js Wyświetl plik

@@ -47,12 +47,14 @@ const Offers = (props) => {
) : (
<OffersContainer ref={offersRef}>
{offers.allOffersToShow.map((item) => {
console.log(item);
return (
<OfferCard
key={item._id}
offer={item}
halfwidth={props.isGrid}
messageUser={messageOneUser}
isMyOffer={item?.userId === userId}
/>
);
})}

+ 2
- 2
src/components/MarketPlace/Offers/Offers.styled.js Wyświetl plik

@@ -19,7 +19,7 @@ export const FilterContainer = styled(IconWithNumber)`
top: ${props => props.myOffers ? "126px" : "93px"};
right: 18px;
cursor: pointer;
background-color: ${selectedTheme.offerBackgroundColor} !important;
background-color: ${selectedTheme.primaryBackgroundColor} !important;
& div {
width: 16px;
height: 16px;
@@ -35,5 +35,5 @@ export const FilterContainer = styled(IconWithNumber)`
}
`;
export const FilterIcon = styled(Filter)`
background-color: ${selectedTheme.offerBackgroundColor};
background-color: ${selectedTheme.primaryBackgroundColor};
`;

+ 0
- 1
src/components/Popovers/HeaderPopover/HeaderPopover.styled.js Wyświetl plik

@@ -39,7 +39,6 @@ export const PopoverListItemProfileAvatar = styled(ProfileAvatar)`
`;
export const PopoverListItemAvatarContainer = styled(ListItemAvatar)``;
export const PopoverButton = styled(Button)`
text-decoration: underline;
color: ${selectedTheme.primaryPurple};
font-weight: 500;
text-align: right;

+ 24
- 0
src/components/Popovers/PhonePopover/PhonePopover.js Wyświetl plik

@@ -0,0 +1,24 @@
import React from "react";
import PropTypes from "prop-types";
import {
Arrow,
PhoneLabel,
PhoneNumber,
PhonePopoverContainer,
} from "./PhonePopover.styled";

const PhonePopover = () => {
return (
<PhonePopoverContainer>
<Arrow />
<PhoneLabel>Broj telefona</PhoneLabel>
<PhoneNumber>065/000-018</PhoneNumber>
</PhonePopoverContainer>
);
};

PhonePopover.propTypes = {
children: PropTypes.node,
};

export default PhonePopover;

+ 44
- 0
src/components/Popovers/PhonePopover/PhonePopover.styled.js Wyświetl plik

@@ -0,0 +1,44 @@
import { Box } from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../../themes";

export const PhonePopoverContainer = styled(Box)`
width: 138px;
height: 49px;
filter: drop-shadow(4px 4px 9px rgba(0, 0, 0, 0.04));
position: relative;
overflow: visible !important;
`;
export const Arrow = styled(Box)`
position: absolute;
width: 13px;
height: 13px;
right: -6px;
top: 18px;
background: white;
border-radius: 0.72px;
transform: rotate(45deg);
`;
export const PhoneLabel = styled(Box)`
color: ${selectedTheme.primaryDarkText};
font-size: 12px;
line-height: 16px;
text-align: center;
align-items: center;
display: flex;
font-family: "Open Sans";
position: relative;
left: 18px;
top: 5px;
`;
export const PhoneNumber = styled(Box)`
position: relative;
left: 18px;
top: 5px;
font-family: "Open Sans";
font-weight: 600;
font-size: 16px;
line-height: 22px;
align-items: center;
color: ${selectedTheme.primaryPurple};
`;

+ 19
- 2
src/components/Popovers/PopoverComponent.js Wyświetl plik

@@ -2,20 +2,32 @@ import React from "react";
import PropTypes from "prop-types";
import { Popover } from "@mui/material";

const PopoverComponent = ({ open, anchorEl, onClose, content }) => {
const PopoverComponent = ({ open, anchorEl, onClose, content, className, anchorRight }) => {
const handleClose = () => {
onClose();
};

return (
<Popover
className={className}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: "bottom",
vertical: anchorRight ? "top" : "bottom",
horizontal: "left",
}}
PaperProps={{
style: {
overflow: "visible",
overflowX: "visible",
overflowY: "visible",
}
}}
transformOrigin={{
vertical: "top",
horizontal: anchorRight ? "right" : "center"
}}
>
{content}
</Popover>
@@ -27,6 +39,11 @@ PopoverComponent.propTypes = {
open: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
content: PropTypes.any,
className: PropTypes.string,
anchorRight: PropTypes.bool,
};
PopoverComponent.defaultProps = {
anchorRight: false,
}

export default PopoverComponent;

+ 21
- 0
src/components/Profile/ProfileOffers/NoProfileOffers.js/NoProfileOffers.js Wyświetl plik

@@ -0,0 +1,21 @@
import React from 'react'
import PropTypes from 'prop-types'
import { NoProfileOffersAltText, NoProfileOffersContainer, NoProfileOffersIcon, NoProfileOffersMainText } from './NoProfileOffers.styled'
import { useTranslation } from 'react-i18next'

const NoProfileOffers = () => {
const {t} = useTranslation();
return (
<NoProfileOffersContainer>
<NoProfileOffersIcon />
<NoProfileOffersMainText>{t("profile.noOffers.mainText")}</NoProfileOffersMainText>
<NoProfileOffersAltText>{t("profile.noOffers.altText")}</NoProfileOffersAltText>
</NoProfileOffersContainer>
)
}

NoProfileOffers.propTypes = {
children: PropTypes.node,
}

export default NoProfileOffers

+ 35
- 0
src/components/Profile/ProfileOffers/NoProfileOffers.js/NoProfileOffers.styled.js Wyświetl plik

@@ -0,0 +1,35 @@
import { Box, Typography } from "@mui/material";
import styled from "styled-components";
import {ReactComponent as HalfLogo} from "../../../../assets/images/svg/half-logo.svg"
import selectedTheme from "../../../../themes";

export const NoProfileOffersContainer = styled(Box)`
text-align: center;
background-color: white;
height: 340px;
display: flex;
flex-direction: column;
border-radius: 4px;
`
export const NoProfileOffersIcon = styled(HalfLogo)`
margin-top: 85px;
text-align: center;
width: 100%;
`
export const NoProfileOffersMainText = styled(Typography)`
font-family: "Open Sans";
font-weight: 700;
font-size: 24px;
text-align: center;
color: ${selectedTheme.primaryPurple};
margin-top: 10px;
line-height: 33px;
`
export const NoProfileOffersAltText = styled(Typography)`
font-family: "Open Sans";
font-size: 16px;
color: ${selectedTheme.primaryGrayText};
text-align: center;
margin-top: 9px;
line-height: 22px;
`

+ 70
- 45
src/components/Profile/ProfileOffers/ProfileOffers.js Wyświetl plik

@@ -22,21 +22,30 @@ import OfferCard from "../../Cards/OfferCard/OfferCard";
import { useTranslation } from "react-i18next";
import { useRef } from "react";
import { selectProfileOffers } from "../../../store/selectors/offersSelectors";
import useScreenDimensions from "../../../hooks/useScreenDimensions";
import { selectLatestChats } from "../../../store/selectors/chatSelectors";
import { useHistory } from "react-router-dom";
import { selectUserId } from "../../../store/selectors/loginSelectors";
import NoProfileOffers from "./NoProfileOffers.js/NoProfileOffers";
import { selectIsLoadingByActionType } from "../../../store/selectors/loadingSelectors";
import { OFFERS_PROFILE_SCOPE } from "../../../store/actions/offers/offersActionConstants";
import SkeletonOfferCard from "../../Cards/OfferCard/SkeletonOfferCard/SkeletonOfferCard";
import useIsMobile from "../../../hooks/useIsMobile";

const ProfileOffers = (props) => {
const [sortOption, setSortOption] = useState(sortEnum.INITIAL);
const [offersToShow, setOffersToShow] = useState([]);
const isLoadingMineOffers = useSelector(
selectIsLoadingByActionType(OFFERS_PROFILE_SCOPE)
);
console.log("isLoadingMineOffers", isLoadingMineOffers);
const searchRef = useRef(null);
const chats = useSelector(selectLatestChats);
const profileOffers = useSelector(selectProfileOffers);
const dimensions = useScreenDimensions();
const { isMobile } = useIsMobile();
const history = useHistory();
const { t } = useTranslation();
const userId = useSelector(selectUserId);
const arrayForMapping = Array.apply(null, Array(4)).map(() => {});

const messageUser = (offer) => {
const chatItem = chats.find(
@@ -74,7 +83,7 @@ const ProfileOffers = (props) => {
}, [sortOption]);

useEffect(() => {
if (profileOffers?.length > 0) setOffersToShow(profileOffers);
if (profileOffers) setOffersToShow(profileOffers);
}, [profileOffers]);

const handleSearch = () => {
@@ -112,22 +121,26 @@ const ProfileOffers = (props) => {

return (
<ProfileOffersContainer>
<HeaderSelect
value={sortOption?.value ? sortOption.value : sortEnum.INITIAL.value}
IconComponent={DownArrow}
onChange={handleChangeSelect}
>
{Object.keys(sortEnum).map((property) => {
return (
<SelectOption
value={sortEnum[property].value}
key={sortEnum[property].value}
>
{sortEnum[property].mainText}
</SelectOption>
);
})}
</HeaderSelect>
{offersToShow.length !== 0 ? (
<HeaderSelect
value={sortOption?.value ? sortOption.value : sortEnum.INITIAL.value}
IconComponent={DownArrow}
onChange={handleChangeSelect}
>
{Object.keys(sortEnum).map((property) => {
return (
<SelectOption
value={sortEnum[property].value}
key={sortEnum[property].value}
>
{sortEnum[property].mainText}
</SelectOption>
);
})}
</HeaderSelect>
) : (
<></>
)}
<Grid
container
direction="row"
@@ -140,33 +153,45 @@ const ProfileOffers = (props) => {
{props.isMyProfile ? "Moje objave" : "Objave kompanije"}
</HeaderTitle>
</Grid>
<SearchInput
fullWidth
ref={searchRef}
onFocus={handleFocusSearch}
onBlur={handleBlurSearch}
// ref={searchRef}
placeholder={t("header.searchOffers")}
italicPlaceholder
InputProps={{
endAdornment: (
<IconContainer onClick={handleSearch}>
<SearchIcon />
</IconContainer>
),
}}
/>
{offersToShow.length !== 0 ? (
<SearchInput
fullWidth
ref={searchRef}
onFocus={handleFocusSearch}
onBlur={handleBlurSearch}
// ref={searchRef}
placeholder={t("header.searchOffers")}
italicPlaceholder
InputProps={{
endAdornment: (
<IconContainer onClick={handleSearch}>
<SearchIcon />
</IconContainer>
),
}}
/>
) : (
<></>
)}
<OffersContainer>
{dimensions.width > 600 ? (
offersToShow.map((item) => (
<OfferCard
isMyOffer={props.isMyProfile}
offer={item}
key={JSON.stringify(item)}
pinned
messageUser={messageUser}
/>
))
{!isMobile ? (
isLoadingMineOffers || isLoadingMineOffers === undefined ? (
arrayForMapping.map((item, index) => (
<SkeletonOfferCard key={index} />
))
) : offersToShow.length !== 0 ? (
offersToShow.map((item) => (
<OfferCard
isMyOffer={props.isMyProfile}
offer={item}
key={JSON.stringify(item)}
pinned
messageUser={messageUser}
/>
))
) : (
<NoProfileOffers />
)
) : (
<OffersScroller hideArrows>
{offersToShow.map((item) => (

+ 10
- 10
src/components/ProfileCard/EditProfile/EditProfile.js Wyświetl plik

@@ -27,8 +27,8 @@ import {
} from "../../../store/actions/profile/profileActions";
import { useDispatch, useSelector } from "react-redux";
import { selectUserId } from "../../../store/selectors/loginSelectors";
import useScreenDimensions from "../../../hooks/useScreenDimensions";
import editProfileValidation from "../../../validations/editProfileValidation";
import useIsMobile from "../../../hooks/useIsMobile";

const EditProfile = (props) => {
const [profileImage, setProfileImage] = useState(props.profile.image);
@@ -36,16 +36,16 @@ const EditProfile = (props) => {
const [showDetails, setShowDetails] = useState(true);
const { t } = useTranslation();
const dispatch = useDispatch();
const dimensions = useScreenDimensions();
const { isMobile } = useIsMobile();
const userId = useSelector(selectUserId);

useEffect(() => {
if (dimensions.width < 600) {
if (isMobile) {
setShowDetails(false);
} else {
setShowDetails(true);
}
}, [dimensions.width]);
}, [isMobile]);

const handleApiResponseSuccess = () => {
dispatch(fetchMineProfile(userId));
@@ -59,12 +59,12 @@ const EditProfile = (props) => {

const formik = useFormik({
initialValues: {
firmName: `${props.profile.company.name}`,
firmPIB: `${props.profile.company.PIB}`,
firmLocation: `${props.profile.company.contacts.location}`,
firmWebsite: `${props.profile.company.contacts.web}`,
firmName: `${props?.profile?.company?.name}`,
firmPIB: `${props?.profile?.company?.PIB}`,
firmLocation: `${props?.profile?.company?.contacts?.location ?? ""}`,
firmWebsite: `${props?.profile?.company?.contacts?.web ?? ""}`,
firmApplink: "",
firmPhone: `${props.profile.company.contacts.telephone}`,
firmPhone: `${props?.profile?.company?.contacts?.telephone ?? ""}`,
firmLogo: profileImage,
},
validationSchema: editProfileValidation,
@@ -197,7 +197,7 @@ const EditProfile = (props) => {
<></>
)}

{dimensions.width > 600 ? (
{!isMobile ? (
<ButtonsContainer>
<SaveButton
type="submit"

+ 16
- 12
src/components/ProfileCard/ProfileContact/ProfileContact.js Wyświetl plik

@@ -17,24 +17,28 @@ const ProfileContact = (props) => {
justifyContent={{ xs: "center", sm: "start" }}
alignItems={{ xs: "start", sm: "center" }}
>
<Stack direction="row">
<LocationIcon isMyProfile={props.isMyProfile} />
<ContactItem isMyProfile={props.isMyProfile} variant="subtitle2">
{props.profile?.company?.contacts?.location}
</ContactItem>
</Stack>
{props.profile?.company?.contacts?.location && (
<Stack direction="row">
<LocationIcon isMyProfile={props.isMyProfile} />
<ContactItem isMyProfile={props.isMyProfile} variant="subtitle2">
{props.profile?.company?.contacts?.location}
</ContactItem>
</Stack>
)}
<Stack direction="row">
<MailIcon isMyProfile={props.isMyProfile} />
<ContactItem isMyProfile={props.isMyProfile} variant="subtitle2">
{props.profile?.email}
</ContactItem>
</Stack>
<Stack direction="row">
<GlobeIcon isMyProfile={props.isMyProfile} />
<ContactItem isMyProfile={props.isMyProfile} variant="subtitle2">
{props.profile?.company?.contacts?.web}
</ContactItem>
</Stack>
{props.profile?.company?.contacts?.web && (
<Stack direction="row">
<GlobeIcon isMyProfile={props.isMyProfile} />
<ContactItem isMyProfile={props.isMyProfile} variant="subtitle2">
{props.profile?.company?.contacts?.web}
</ContactItem>
</Stack>
)}
</ProfileContactContainer>
);
};

+ 3
- 3
src/components/UserReviews/NoReviews/NoReviews.js Wyświetl plik

@@ -1,6 +1,5 @@
import React from "react";
import PropTypes from "prop-types";
import useScreenDimensions from "../../../hooks/useScreenDimensions";
import {
NoReviewsAltText,
NoReviewsContainer,
@@ -8,14 +7,15 @@ import {
} from "./NoReviews.styled";
import UserReviewsSkeleton from "./UserReviewsSkeleton/UserReviewsSkeleton";
import { useTranslation } from "react-i18next";
import useIsMobile from "../../../hooks/useIsMobile";
const NoReviews = () => {
const { width } = useScreenDimensions();
const { isMobile } = useIsMobile();
const { t } = useTranslation();
return (
<NoReviewsContainer>
<NoReviewsText>{t("reviews.title")}</NoReviewsText>
<NoReviewsAltText>{t("reviews.altTitle")}</NoReviewsAltText>
<UserReviewsSkeleton numOfElements={width < 600 ? 1 : 2} />
<UserReviewsSkeleton numOfElements={isMobile ? 1 : 2} />
</NoReviewsContainer>
);
};

+ 1
- 1
src/components/UserReviews/UserReviews.styled.js Wyświetl plik

@@ -10,7 +10,7 @@ export const ReviewsBox = styled(Box)`
/* height: ${props => props.numOfReviews > 0 ? props.numOfReviews * 185 + 82 + 'px' : `calc(100% - 90px)`}; */
/* max-height: 100vh; */
@media (max-width: 1200px) {
padding: 0;
padding: 0 50px;
}
@media (max-width: 600px) {
position: relative;

+ 19
- 0
src/hooks/useIsMobile.js Wyświetl plik

@@ -0,0 +1,19 @@
import { useEffect, useState } from "react";

const useIsMobile = () => {
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
const resize = () => {
if (window.innerWidth < 600) {
if (!isMobile) setIsMobile(true);
} else {
if (isMobile) setIsMobile(false);
}
};
window.addEventListener("resize", resize);
resize();
return () => window.removeEventListener("resize", resize);
}, []);
return { isMobile };
};
export default useIsMobile;

+ 6
- 0
src/hooks/useOffers/useMyOffers.js Wyświetl plik

@@ -22,6 +22,11 @@ const useMyOffers = () => {
dispatch(fetchMineOffers());
}, []);

const clear = () => {
filters.clear();
setAppliedFilters(false);
}

const apply = () => {
paging.changePage(1);
setAppliedFilters(false);
@@ -96,6 +101,7 @@ const useMyOffers = () => {
allOffersToShow,
totalOffers,
apply,
clear,
};
};
export default useMyOffers;

+ 4
- 0
src/i18n/resources/rs.js Wyświetl plik

@@ -249,5 +249,9 @@ export default {
numberOfViews: " ukupnih pregleda",
successComunication: " korektna komunikacija",
back: "Nazad na objave",
noOffers: {
mainText: "Objave nisu pronađene",
altText: "Nažalost nemate ni jednu objavu"
}
},
};

+ 1
- 1
src/pages/HomePage/HomePage.styled.js Wyświetl plik

@@ -10,7 +10,7 @@ export const HomePageContainer = styled(Container)`
flex: 1;
display: flex;
flex-direction: column;
background-color: ${selectedTheme.offerBackgroundColor};
background-color: ${selectedTheme.primaryBackgroundColor};
`;
export const GridStyled = styled(Grid)`

+ 20
- 10
src/pages/RegisterPages/Register/FirstPart/FirstPartOfRegistration.js Wyświetl plik

@@ -21,13 +21,6 @@ const FirstPartOfRegistration = (props) => {
const [emailTakenStatus, setEmailTakenStatus] = useState(false);
const { t } = useTranslation();

useEffect(() => {
if (props.informations?.mail) {
formik.setFieldValue("mail", props.informations.mail);
formik.setFieldValue("password", props.informations.password)
}
}, [props.informations])

useEffect(() => {
if (props.error.length > 0) {
setEmailTakenStatus(true);
@@ -36,8 +29,8 @@ const FirstPartOfRegistration = (props) => {

const formik = useFormik({
initialValues: {
mail: "",
password: "",
mail: props.informations?.mail ?? "",
password: props.informations?.password ?? "",
},
validationSchema: firstPartValidation,
onSubmit: props.handleSubmit,
@@ -45,11 +38,28 @@ const FirstPartOfRegistration = (props) => {
enableReinitialize: true,
});

const handleSubmitForm = (event) => {
event.preventDefault();
console.log(formik);
if (!formik.isValid) {
if (formik.errors.mail) {
formik.setFieldValue("mail", "");
formik.setFieldTouched("mail", true);
}
if (formik.errors.password) {
formik.setFieldValue("password", "");
formik.setFieldTouched("password", true);
}
} else {
formik.handleSubmit(event)
}
}

const handleClickShowPassword = () => {
setShowPassword((prevState) => !prevState);
};
return (
<FormContainer component="form" onSubmit={formik.handleSubmit}>
<FormContainer component="form" onSubmit={handleSubmitForm}>
<RegisterDescription component="p" variant="p">
{t("register.descriptionFirst")}
</RegisterDescription>

+ 2
- 1
src/pages/RegisterPages/Register/Register.js Wyświetl plik

@@ -71,6 +71,7 @@ const Register = () => {
}
};


const registerUser = (values) => {
dispatch(
fetchRegisterUser({ values, handleResponseSuccess, handleResponseError })
@@ -173,7 +174,7 @@ const Register = () => {
</LoginTextContainer>
</RegisterPageContent>

<Footer>
<Footer currentStep={currentStep}>
<FooterText>
<Trans i18nKey="register.acceptTerms" />{" "}
<NavLink

+ 16
- 14
src/pages/RegisterPages/Register/Register.styled.js Wyświetl plik

@@ -12,18 +12,23 @@ export const RegisterPageContainer = styled(Container)`
width: 335px;
padding: 0;
flex: 1;
position: relative;
/* position: relative; */
transition: 1s all;
${props => props.currentstep === 3 && `margin-top: 40px`};
margin-bottom: 60px;
${(props) => props.currentstep === 3 && `margin-top: 40px;`};
@media (max-height: 900px) {
margin-top: 60px;
}
@media (max-height: 800px) {
margin-top: 30px;
flex: none;
height: 95vh;
${(props) => props.currentstep === 3 && `height: 105vh`};
${(props) => props.currentstep === 2 && `height: 100vh`};
/* flex: none; */
/* height: 95vh; */
/* ${(props) => props.currentstep === 3 && `height: 105vh`};
${(props) => props.currentstep === 2 && `height: 100vh`}; */
}
@media (max-width: 600px) {
margin-bottom: 60px;
}
`;
export const RegisterTitle = styled(Typography)`
@@ -83,15 +88,12 @@ export const ProgressContainer = styled(Container)`
padding: 0;
`;
export const Footer = styled(Box)`
position: relative;
bottom: 36px;
position: absolute;
bottom: -48px;
display: flex;
width: 100%;
flex-direction: row;
justify-content: center;
@media (max-height: 800px) {
bottom: 10px;
}
`;
export const FooterText = styled(Typography)`
font-family: "Open Sans";
@@ -128,13 +130,13 @@ export const RegisterPageContent = styled(Box)`
padding: 0;
flex: 1;
position: relative;
margin-bottom: 100px;
@media (max-height: 800px) {
/* margin-bottom: 100px; */
/* @media (max-height: 800px) {
flex: none;
height: 95vh;
${(props) => props.currentstep === 3 && `height: 105vh`};
${(props) => props.currentstep === 2 && `height: 100vh`};
}
} */
`;
export const ErrorMessage = styled(Box)`
color: red;
@@ -144,4 +146,4 @@ export const ErrorMessage = styled(Box)`
text-align: left;
font-size: 14px;
width: 100%;
`
`;

+ 0
- 1
src/request/index.js Wyświetl plik

@@ -5,7 +5,6 @@ const request = axios.create({
// baseURL: "http://192.168.88.150:3001/",
// baseURL: "http://192.168.88.175:3005/",
baseURL: "https://trampa-api-test.dilig.net/",

headers: {
"Content-Type": "application/json",
},

+ 8
- 2
src/store/saga/profileSaga.js Wyświetl plik

@@ -61,8 +61,8 @@ function* changeMineProfile(payload) {
name: payload.payload.firmName,
PIB: payload.payload.firmPIB,
contacts: {
telephone: payload.payload.firmPhone,
location: payload.payload.firmLocation,
telephone: payload.payload.firmPhone.toString(),
location: payload.payload.firmLocation ?? "",
web: payload.payload.firmWebsite,
},
},
@@ -70,6 +70,12 @@ function* changeMineProfile(payload) {
};

if (payload.payload.firmLogo.includes("https")) delete reqData.image;
if (reqData.company.contacts.telephone.length === 0)
delete reqData.company.contacts.telephone;
if (reqData.company.contacts.location.length === 0)
delete reqData.company.contacts.location;
if (reqData.company.contacts.web.length === 0)
delete reqData.company.contacts.web;

const userId = yield select(selectUserId);
const data = yield call(attemptEditProfile, userId, reqData);

+ 1
- 0
src/util/helpers/queryHelpers.js Wyświetl plik

@@ -20,6 +20,7 @@ import {
VALUE_SORTBY_POPULAR,
} from "../../constants/queryStringConstants";
import { sortEnum } from "../../enums/sortEnum";
// import { ReactComponent as CategoryHeader } from "../../assets/images/svg/category-header.svg"
// import qs from "query-string";

export const convertQueryStringForFrontend = (queryURL) => {

+ 5
- 4
src/validations/registerValidations/firstPartValidation.js Wyświetl plik

@@ -1,4 +1,6 @@
import * as Yup from "yup";
import YupPassword from 'yup-password';
YupPassword(Yup);
import i18n from "../../i18n";
export default Yup.object().shape({
mail: Yup.string()
@@ -7,8 +9,7 @@ export default Yup.object().shape({
password: Yup.string()
.required(i18n.t("login.passwordRequired"))
.min(8, i18n.t("login.passwordLength"))
.matches(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[#$^+=!*()@%&]).{8,25}$/g,
i18n.t("password.strongPassword")
),
.minLowercase(1, i18n.t("password.strongPassword"))
.minUppercase(1, i18n.t("password.strongPassword"))
.minSymbols(1, i18n.t("password.strongPassword")),
});

Ładowanie…
Anuluj
Zapisz