Pārlūkot izejas kodu

Changed API routes

feature/code-cleanup-joca
Djordje Mitrovic pirms 3 gadiem
vecāks
revīzija
9c6b0730bf
40 mainītis faili ar 569 papildinājumiem un 834 dzēšanām
  1. 0
    20
      src/components/Auth/Auth.js
  2. 0
    24
      src/components/AuthCards/AuthCard.js
  3. 16
    11
      src/components/Buttons/ArrowButton/ArrowButton.js
  4. 0
    93
      src/components/Buttons/Button.js
  5. 25
    15
      src/components/Buttons/IconButton/IconButton.js
  6. 12
    8
      src/components/Buttons/IconButton/IconButton.styled.js
  7. 0
    26
      src/components/Buttons/LoginButton/LoginButton.js
  8. 0
    11
      src/components/Buttons/LoginButton/LoginButton.styled.js
  9. 0
    34
      src/components/Buttons/PrimaryButtonWithIcon/PrimaryButtonWithIcon.js
  10. 0
    28
      src/components/Buttons/PrimaryButtonWithIcon/PrimaryButtonWithIcon.styled.js
  11. 34
    30
      src/components/Cards/ChatCard/ChatCard.js
  12. 5
    193
      src/components/Cards/ChatCard/ChatCard.styled.js
  13. 46
    0
      src/components/Cards/FilterCard/Choser/CategoryChoser/CategoryChoser.js
  14. 8
    0
      src/components/Cards/FilterCard/Choser/CategoryChoser/CategoryChoser.styled.js
  15. 30
    0
      src/components/Cards/FilterCard/Choser/LocationChoser/LocationChoser.js
  16. 5
    0
      src/components/Cards/FilterCard/Choser/LocationChoser/LocationChoser.styled.js
  17. 63
    0
      src/components/Cards/FilterCard/Choser/SubcategoryChoser/SubcategoryChoser.js
  18. 4
    0
      src/components/Cards/FilterCard/Choser/SubcategoryChoser/SubcategoryChoser.styled.js
  19. 15
    141
      src/components/Cards/FilterCard/FilterCard.js
  20. 3
    36
      src/components/Cards/FilterCard/FilterCard.styled.js
  21. 7
    4
      src/components/Cards/FilterCard/FilterDropdown/Radio/FilterRadioDropdown.js
  22. 61
    0
      src/components/Cards/FilterCard/FilterFooter/FilterFooter.js
  23. 22
    0
      src/components/Cards/FilterCard/FilterFooter/FilterFooter.styled.js
  24. 28
    0
      src/components/Cards/FilterCard/FilterHeader/FilterHeader.js
  25. 19
    0
      src/components/Cards/FilterCard/FilterHeader/FilterHeader.styled.js
  26. 0
    19
      src/components/Cards/HomeListCard/HomeListCard.js
  27. 29
    0
      src/components/Cards/ItemDetailsCard/Information/Information.js
  28. 20
    0
      src/components/Cards/ItemDetailsCard/Information/Information.styled.js
  29. 39
    110
      src/components/Cards/ItemDetailsCard/ItemDetailsCard.js
  30. 20
    17
      src/components/Cards/ItemDetailsCard/ItemDetailsCard.styled.js
  31. 14
    0
      src/components/Cards/ItemDetailsCard/OfferDetails/OfferDetails.js
  32. 0
    0
      src/components/Cards/ItemDetailsCard/OfferDetails/OfferDetails.styled.js
  33. 2
    4
      src/components/Cards/MiniChatCard/MiniChatCard.js
  34. 5
    0
      src/hooks/useFilters.js
  35. 5
    0
      src/i18n/resources/rs.js
  36. 0
    7
      src/pages/ErrorPages/NotFoundPage.js
  37. 2
    2
      src/request/apiEndpoints.js
  38. 1
    1
      src/request/offersRequest.js
  39. 16
    0
      src/util/helpers/chatHelper.js
  40. 13
    0
      src/util/helpers/dateHelpers.js

+ 0
- 20
src/components/Auth/Auth.js Parādīt failu

import React from 'react';
import PropTypes from 'prop-types';
import { useTranslation } from 'react-i18next';

const Auth = ({ children }) => {
const { t } = useTranslation();

return (
<div className="c-auth">
<h1 className="c-auth__title">{t(`login.welcome`)}</h1>
{children}
</div>
);
};

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

export default Auth;

+ 0
- 24
src/components/AuthCards/AuthCard.js Parādīt failu

import React from 'react';
import PropTypes from 'prop-types';
import SectionLoader from '../Loader/SectionLoader';

const AuthCard = ({ children, title, subtitle, isLoading }) => {
return (
<div className="c-auth-card">
<SectionLoader isLoading={isLoading}>
<h1 className="c-auth-card__title">{title}</h1>
<h2 className="c-auth-card__subtitle">{subtitle}</h2>
{children}
</SectionLoader>
</div>
);
};

AuthCard.propTypes = {
children: PropTypes.node,
title: PropTypes.string,
subtitle: PropTypes.string,
isLoading: PropTypes.bool,
};

export default AuthCard;

+ 16
- 11
src/components/Buttons/ArrowButton/ArrowButton.js Parādīt failu

import React from 'react'
import { ArrowContainer, ArrowIcon } from "./ArrowButton.styled"
import React from "react";
import { ArrowContainer, ArrowIcon } from "./ArrowButton.styled";
import PropTypes from "prop-types"; import PropTypes from "prop-types";


export const ArrowButton = (props) => { export const ArrowButton = (props) => {

return <ArrowContainer onClick={props.onClick} className={props.className} disabled={props.disabled}>
<ArrowIcon side={props.side} disabled={props.disabled}/>
return (
<ArrowContainer
onClick={props.onClick}
className={props.className}
disabled={props.disabled}
>
<ArrowIcon side={props.side} disabled={props.disabled} />
</ArrowContainer> </ArrowContainer>
}
);
};


ArrowButton.propTypes = { ArrowButton.propTypes = {
onClick: PropTypes.func,
className: PropTypes.string,
side:PropTypes.string,
disabled:PropTypes.bool,
}
onClick: PropTypes.func,
className: PropTypes.string,
side: PropTypes.string,
disabled: PropTypes.bool,
};

+ 0
- 93
src/components/Buttons/Button.js Parādīt failu

import React, { useRef } from 'react';
import PropType from 'prop-types';

const Button = ({
variant,
size,
children,
authButton,
type,
onClick,
textTransform,
className,
disabled,
hidden,
minWidth,
...restProps
}) => {
const buttonRef = useRef(null);

function styles() {
let style = 'c-btn';

if (variant) {
style += ` c-btn--${variant}`;
}

if (size) {
style += ` c-btn--${size}`;
}

if (textTransform) {
style += ` c-btn--${textTransform}`;
}

if (authButton) {
style += ` c-btn--auth`;
}

if (minWidth) {
style += ` c-btn--${minWidth}`;
}

if (hidden) {
style += ` c-btn--hidden`;
}

if (className) {
style += ` ${className}`;
}

return style;
}

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

return (
<button
ref={buttonRef}
className={styles()}
onClick={handleClick}
type={type}
disabled={disabled}
{...restProps}
>
{children}
</button>
);
};

Button.propTypes = {
children: PropType.node,
textTransform: PropType.oneOf(['uppercase', 'capitalize']),
size: PropType.oneOf(['sm', 'md', 'lg', 'xl']),
authButton: PropType.bool,
variant: PropType.string,
type: PropType.oneOf(['button', 'submit', 'reset']),
onClick: PropType.func,
className: PropType.string,
disabled: PropType.bool,
minWidth: PropType.oneOf(['auto']),
hidden: PropType.bool,
};

Button.defaultProps = {
type: 'button',
};

export default Button;

+ 25
- 15
src/components/Buttons/IconButton/IconButton.js Parādīt failu

import React from 'react'
import { IconButtonContainer, IconButtonStyled } from "./IconButton.styled"
import React from "react";
import { IconButtonContainer, IconButtonStyled } from "./IconButton.styled";
import PropTypes from "prop-types"; import PropTypes from "prop-types";


export const IconButton = (props) => { export const IconButton = (props) => {
return <IconButtonContainer style={props.containerStyle} className={props.className}>
<IconButtonStyled disabled={props.disabled} onClick={props.onClick} sx={props.style} iconcolor={props.iconColor}>
{props.children}
</IconButtonStyled>
return (
<IconButtonContainer
style={props.containerStyle}
className={props.className}
>
<IconButtonStyled
disabled={props.disabled}
onClick={props.onClick}
sx={props.style}
iconcolor={props.iconColor}
>
{props.children}
</IconButtonStyled>
</IconButtonContainer> </IconButtonContainer>
}
);
};


IconButton.propTypes = { IconButton.propTypes = {
children: PropTypes.node,
onClick: PropTypes.func,
containerStyle: PropTypes.any,
style: PropTypes.any,
className: PropTypes.string,
iconColor: PropTypes.string,
disabled: PropTypes.bool,
}
children: PropTypes.node,
onClick: PropTypes.func,
containerStyle: PropTypes.any,
style: PropTypes.any,
className: PropTypes.string,
iconColor: PropTypes.string,
disabled: PropTypes.bool,
};

+ 12
- 8
src/components/Buttons/IconButton/IconButton.styled.js Parādīt failu

import styled from "styled-components"; import styled from "styled-components";
import selectedTheme from "../../../themes"; import selectedTheme from "../../../themes";


export const IconButtonContainer = styled(Box)`
`
export const IconButtonContainer = styled(Box)``;


export const IconButtonStyled = styled(IconButton)` export const IconButtonStyled = styled(IconButton)`
height: ${props => props.height ? props.height : "36px"};
width: ${props => props.width ? props.width : "36px"};
padding: 0;
${props => props.iconcolor && `
height: ${(props) => (props.height ? props.height : "36px")};
width: ${(props) => (props.width ? props.width : "36px")};
padding: 0;
${(props) =>
props.iconcolor &&
`
& svg path { & svg path {
stroke: ${props.iconcolor}; stroke: ${props.iconcolor};
} }
`} `}
border: ${props => props.border ? "1px solid " + selectedTheme.backgroundSponsoredColor : "none"}
`
border: ${(props) =>
props.border
? "1px solid " + selectedTheme.backgroundSponsoredColor
: "none"}
`;

+ 0
- 26
src/components/Buttons/LoginButton/LoginButton.js Parādīt failu

import React from "react";
import { LoginButtonContainer, LoginButtonStyled } from "./LoginButton.styled";
import PropTypes from "prop-types";


//Currently not in use
export const LoginButton = (props) => {
return (
<LoginButtonContainer style={props.containerStyle}>
<LoginButtonStyled {...props} sx={props.style} variant="contained">
Dugme
</LoginButtonStyled>
</LoginButtonContainer>
);
};

LoginButton.propTypes = {
children: PropTypes.node,
type: PropTypes.string,
variant: PropTypes.string,
style: PropTypes.any,
containerStyle: PropTypes.any,
fullWidth: PropTypes.bool,
buttonColor: PropTypes.string,
onClick: PropTypes.func
};

+ 0
- 11
src/components/Buttons/LoginButton/LoginButton.styled.js Parādīt failu

import { Box, Button } from "@mui/material";
import styled from "styled-components";


export const LoginButtonContainer = styled(Box)`
`

export const LoginButtonStyled = styled(Button)`
background-color: ${props => props.backgroundColor};
color: ${props => props.textColor}
`

+ 0
- 34
src/components/Buttons/PrimaryButtonWithIcon/PrimaryButtonWithIcon.js Parādīt failu

import React from "react";
import PropTypes from "prop-types";
import {
PrimaryButtonWithIconContainer,
IconStyled,
PrimaryButtonWithIconStyled,
} from "./PrimaryButtonWithIcon.styled";

const PrimaryButtonWithIcon = (props) => {
return (
<PrimaryButtonWithIconContainer
style={props.containerStyle}
className={props.className}
>
<PrimaryButtonWithIconStyled sx={props.style} {...props.buttonProps} onClick={props.onClick}>
<IconStyled style={props.iconStyle}>{props.icon}</IconStyled>
{props.children}
</PrimaryButtonWithIconStyled>
</PrimaryButtonWithIconContainer>
);
};

PrimaryButtonWithIcon.propTypes = {
children: PropTypes.node,
icon: PropTypes.node,
className: PropTypes.string,
containerStyle: PropTypes.any,
style: PropTypes.any,
iconStyle: PropTypes.any,
buttonProps: PropTypes.any,
onClick: PropTypes.func,
};

export default PrimaryButtonWithIcon;

+ 0
- 28
src/components/Buttons/PrimaryButtonWithIcon/PrimaryButtonWithIcon.styled.js Parādīt failu

import { Box } from "@mui/material";
import styled from "styled-components";
import { Icon } from "../../Icon/Icon";
import { PrimaryButton } from "../PrimaryButton/PrimaryButton";

export const PrimaryButtonWithIconContainer = styled(Box)``;

export const PrimaryButtonWithIconStyled = styled(PrimaryButton)`
position: relative;
`;

export const IconStyled = styled(Icon)`
position: absolute;
padding: 0;
left: 10px;
top: 0;
bottom: 0;
margin-top: auto;
margin-bottom: auto;
line-height: 21px;
& span {
position: absolute;
top: 0;
bottom: 0;
margin-top: auto;
margin-bottom: auto;
}
`;

+ 34
- 30
src/components/Cards/ChatCard/ChatCard.js Parādīt failu

import React, { useEffect, useState } from "react";
import React, { useMemo } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { import {
CheckButton, CheckButton,
OfferImage, OfferImage,
OfferTitle, OfferTitle,
OfferCard,
ChatOffer, ChatOffer,
Commands, Commands,
ChatInfo, ChatInfo,
OfferTitleMobile, OfferTitleMobile,
PhoneIconContainer, PhoneIconContainer,
PhoneIcon, PhoneIcon,
LocationIconContainer,
} from "./ChatCard.styled"; } from "./ChatCard.styled";
import { ReactComponent as Location } from "../../../assets/images/svg/location.svg";
import selectedTheme from "../../../themes"; import selectedTheme from "../../../themes";
import { useHistory } from "react-router-dom"; import { useHistory } from "react-router-dom";
import useScreenDimensions from "../../../hooks/useScreenDimensions"; import useScreenDimensions from "../../../hooks/useScreenDimensions";
//import { useSelector } from "react-redux";
import { useTranslation } from "react-i18next";


const ChatCard = (props) => { const ChatCard = (props) => {
const history = useHistory(); const history = useHistory();
const dimensions = useScreenDimensions(); const dimensions = useScreenDimensions();
const [isMobile, setIsMobile] = useState(dimensions.width < 600);
const chat = props.chat;
const { t } = useTranslation();


useEffect(() => {
const resize = (e) => {
if (e.target.outerWidth < 600 && isMobile) setIsMobile(false);
else if (e.target.outerWidth > 600 && !isMobile) setIsMobile(true);
};
window.addEventListener("resize", resize);
const chat = useMemo(() => {
return props.chat;
}, [props.chat]);


return () => window.removeEventListener("resize", resize);
}, []);
const lastMessage = useMemo(() => {
if (chat?.chat?.messages && chat?.chat?.messages?.length > 0) {
return chat.chat.messages[chat.chat.messages.length - 1]?.text;
}
return "";
}, [chat]);


const routeToItem = (userId) => {
history.push(`/messages/${userId}`);
const routeToItem = () => {
history.push(`/messages/${chat?.chat?._id}`);
}; };
return ( return (
<ChatCardContainer onClick={isMobile ? () => routeToItem(chat?.chat?._id) : () => {}}>
<ChatCardContainer
onClick={
dimensions.width < 600 ? () => routeToItem(chat?.chat?._id) : () => {}
}
>
<Col> <Col>
<UserImgWrapper> <UserImgWrapper>
<UserImage src={chat?.interlocutorData?.image} /> <UserImage src={chat?.interlocutorData?.image} />


<ChatInfo> <ChatInfo>
<UserName>{chat?.interlocutorData?.name}</UserName> <UserName>{chat?.interlocutorData?.name}</UserName>

{/* Only shows on Mobile */} {/* Only shows on Mobile */}
<OfferCardContainerMobile> <OfferCardContainerMobile>
<OfferTextMobile>Proizvod:</OfferTextMobile>
<OfferTextMobile>{t("messages.cardProduct")}</OfferTextMobile>
<OfferTitleMobile>{chat?.offerData?.name}</OfferTitleMobile> <OfferTitleMobile>{chat?.offerData?.name}</OfferTitleMobile>
</OfferCardContainerMobile> </OfferCardContainerMobile>
{/* ^^^^^ */} {/* ^^^^^ */}
<LastMessage>
{chat?.chat?.messages
? chat?.chat?.messages[chat?.chat?.messages?.length - 1]?.text
: ""}
</LastMessage>

<LastMessage>{lastMessage}</LastMessage>
<LocationContainer> <LocationContainer>
<LocationIcon>
<Location height="12px" width="12px" />
</LocationIcon>
<LocationIconContainer>
<LocationIcon />
</LocationIconContainer>
<XSText>{chat?.interlocutorData?.location}</XSText> <XSText>{chat?.interlocutorData?.location}</XSText>
</LocationContainer> </LocationContainer>
</ChatInfo> </ChatInfo>
</Col> </Col>
<Line /> <Line />


{/* Only shows on Desktop */}
<Col mobileDisappear> <Col mobileDisappear>
<ChatOffer> <ChatOffer>
<OfferImgWrapper> <OfferImgWrapper>
<OfferImage src={chat?.offerData?.firstImage} /> <OfferImage src={chat?.offerData?.firstImage} />
</OfferImgWrapper> </OfferImgWrapper>
<OfferCardContainer> <OfferCardContainer>
<OfferText>Proizvod:</OfferText>
<OfferText>{t("messages.cardProduct")}</OfferText>
<OfferTitle>{chat?.offerData?.name}</OfferTitle> <OfferTitle>{chat?.offerData?.name}</OfferTitle>
</OfferCardContainer> </OfferCardContainer>
</ChatOffer> </ChatOffer>
</Col> </Col>
{/* ^^^^^^^ */}

<Commands> <Commands>
<PhoneIconContainer> <PhoneIconContainer>
<PhoneIcon /> <PhoneIcon />
textcolor={selectedTheme.primaryPurple} textcolor={selectedTheme.primaryPurple}
variant={"outlined"} variant={"outlined"}
style={{ fontWeight: "600" }} style={{ fontWeight: "600" }}
onClick={() => routeToItem(chat?.chat?._id)}
onClick={routeToItem}
> >
Pogledaj caskanje
{t("messages.seeChats")}
</CheckButton> </CheckButton>
</Commands> </Commands>
</ChatCardContainer> </ChatCardContainer>
vertical: PropTypes.bool, vertical: PropTypes.bool,
chat: PropTypes.any, chat: PropTypes.any,
}; };
OfferCard.defaultProps = {
ChatCard.defaultProps = {
halfwidth: false, halfwidth: false,
sponsored: false, sponsored: false,
}; };

+ 5
- 193
src/components/Cards/ChatCard/ChatCard.styled.js Parādīt failu

import selectedTheme from "../../../themes"; import selectedTheme from "../../../themes";
import { IconButton } from "../../Buttons/IconButton/IconButton"; import { IconButton } from "../../Buttons/IconButton/IconButton";
import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton"; import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton";
import { Icon } from "../../Icon/Icon";
import { ReactComponent as Eye } from "../../../assets/images/svg/eye-striked.svg";
import { ReactComponent as Phone } from "../../../assets/images/svg/phone.svg"; import { ReactComponent as Phone } from "../../../assets/images/svg/phone.svg";
import { ReactComponent as Location } from "../../../assets/images/svg/location.svg";


export const ChatCardContainer = styled(Container)` export const ChatCardContainer = styled(Container)`
display: flex; display: flex;
min-width: 72px; min-width: 72px;
max-width: 72px; max-width: 72px;
`; `;

export const OfferFlexContainer = styled(Container)`
display: flex;
flex-direction: row;
margin: 0;
padding: 0;
max-height: 184px;
@media (max-width: 600px) {
${(props) =>
props.vertical &&
`
flex-direction: column;
`}
}
export const LocationIcon = styled(Location)`
height: 12px;
width: 12px;
`; `;


export const OfferCardContainer = styled(Container)` export const OfferCardContainer = styled(Container)`
} }
`; `;


export const OfferInfo = styled(Box)`
display: flex;
flex: 2;
flex-direction: column;
justify-content: space-between;
margin-left: 18px;
${(props) =>
props.vertical &&
`
margin-left: 0;
margin-top: 5px;
`}
`;
export const OfferTitle = styled(Typography)` export const OfferTitle = styled(Typography)`
font-family: "Open Sans"; font-family: "Open Sans";
flex: 1; flex: 1;
} }
`; `;


export const OfferAuthor = styled(Box)`
display: flex;
flex: 1;
flex-direction: column;
`;
export const OfferAuthorName = styled(Typography)`
font-family: "Open Sans";
line-height: 22px;
font-size: 16px;
color: ${selectedTheme.primaryText};
@media (max-width: 600px) {
font-size: 14px;
${(props) =>
props.vertical &&
`
line-height: 19px;
font-size: 14px;
position: absolute;
bottom: 80px;
`}
}
`;
export const OfferLocation = styled(Typography)`
font-family: "Open Sans";
color: ${selectedTheme.primaryDarkText};
line-height: 16px;
font-size: 12px;
${(props) =>
props.vertical &&
`
font-size: 12px;
margin-top: 5px;
position: absolute;
bottom: 61px;
`}
`;
export const OfferDetails = styled(Box)`
display: flex;
flex-direction: row;
flex-wrap: ${(props) => (!props.halfwidth ? "no-wrap" : "wrap")};
justify-content: start;
gap: 1rem;
@media (max-width: 650px) {
flex-direction: column;
justify-content: center;
gap: 0;
}
`;
export const OfferCategory = styled(Box)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
${(props) =>
props.vertical &&
`
position: absolute;
bottom: 15px;
`}
`;
export const OfferPackage = styled(Box)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
`;
export const OfferViews = styled(Box)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
${(props) =>
props.vertical &&
`
display: none;
`}
`;
export const OfferDescriptionTitle = styled(Box)`
font-family: "Open Sans";
font-size: 12px;
color: ${selectedTheme.primaryDarkText};
line-height: 16px;
`;
export const OfferDescriptionText = styled(Box)`
font-family: "Open Sans";
font-size: 16px;
color: ${selectedTheme.primaryDarkText};
line-height: 22px;
max-width: calc(100% - 230px);
max-height: 120px;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 5;
-webkit-box-orient: vertical;
@media (max-width: 1500px) {
display: none;
}
`;
export const OfferDescription = styled(Box)`
flex: 3;
margin: auto 0;
padding-left: 35px;
@media (max-width: 1500px) {
display: none;
}
`;

export const DetailIcon = styled(Icon)`
& svg {
width: 14px;
position: relative;
top: -1px;
}
`;
export const DetailText = styled(Typography)`
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
line-height: 16px;
font-size: 12px;
position: relative;
top: -2px;
left: 3px;
`;
export const CheckButton = styled(PrimaryButton)` export const CheckButton = styled(PrimaryButton)`
width: 180px; width: 180px;
height: 48px; height: 48px;
} }
} }
`; `;
export const OfferImageContainer = styled(Box)`
min-width: 144px;
min-height: 144px;
width: 144px;
height: 144px;
@media (max-width: 600px) {
${(props) =>
!props.vertical
? `
min-width: 108px;
min-height: 108px;
width: 108px;
height: 108px;
`
: `margin-top: 4px;`}
border-radius: 4px;
overflow: hidden;
box-shadow: 4px 4px 9px rgba(0, 0, 0, 0.12);
}
`;
export const OfferTitleAboveImage = styled(OfferTitle)`
padding-bottom: 12px;
padding-top: 5px;
padding-left: 1px;
display: block;
${(props) => props.vertical && `display: none;`}
@media (min-width: 551px) {
display: none;
}
`;
export const EyeIcon = styled(Eye)`
width: 12px;
height: 11px;
@media (max-width: 600px) {
position: relative;
top: 1px !important;
}
`;


export const ChatOffer = styled(Box)` export const ChatOffer = styled(Box)`
display: flex; display: flex;
} }
`; `;


export const OfferCard = styled(Box)``;

export const ChatInfo = styled(Box)` export const ChatInfo = styled(Box)`
height: 100%; height: 100%;
display: flex; display: flex;
} }
`; `;


export const LocationIcon = styled(Box)`
export const LocationIconContainer = styled(Box)`
height: 12px; height: 12px;
width: auto; width: auto;
position: relative; position: relative;

+ 46
- 0
src/components/Cards/FilterCard/Choser/CategoryChoser/CategoryChoser.js Parādīt failu

import React from "react";
import PropTypes from "prop-types";
import FilterRadioDropdown from "../../FilterDropdown/Radio/FilterRadioDropdown";
import { CategoryChosenIcon, CategoryIcon } from "./CategoryChoser.styled";
import { useTranslation } from "react-i18next";

const firstCategoryOption = {
label: "SVE KATEGORIJE",
value: { _id: 0 },
};

const CategoryChoser = (props) => {
const filters = props.filters;
const { t } = useTranslation();
const handleSelectCategory = (category) => {
filters.setSelectedCategory(category);
filters.clearSelectedSubcategory();
};
return (
<FilterRadioDropdown
data={[...filters?.categories]}
icon={
filters.selectedCategory?.name ? (
<CategoryChosenIcon />
) : (
<CategoryIcon />
)
}
title={
filters.selectedCategory?.name
? filters.selectedCategory?.name
: t("filters.categories.title")
}
searchPlaceholder={t("filters.categories.placeholder")}
setSelected={handleSelectCategory}
selected={filters.selectedCategory}
firstOption={firstCategoryOption}
/>
);
};

CategoryChoser.propTypes = {
filters: PropTypes.any,
};

export default CategoryChoser;

+ 8
- 0
src/components/Cards/FilterCard/Choser/CategoryChoser/CategoryChoser.styled.js Parādīt failu

import { ReactComponent as Category } from "../../../../../assets/images/svg/category.svg";
import { ReactComponent as CategoryChosen } from "../../../../../assets/images/svg/category-chosen.svg";
import styled from "styled-components"

export const CategoryChosenIcon = styled(CategoryChosen)`
`
export const CategoryIcon = styled(Category)`
`

+ 30
- 0
src/components/Cards/FilterCard/Choser/LocationChoser/LocationChoser.js Parādīt failu

import React from "react";
import PropTypes from "prop-types";
import FilterCheckboxDropdown from "../../FilterDropdown/Checkbox/FilterCheckboxDropdown";
import { LocationIcon } from "./LocationChoser.styled";
import { useTranslation } from "react-i18next";

const LocationChoser = (props) => {
const { t } = useTranslation();
const filters = props.filters;
return (
<FilterCheckboxDropdown
searchPlaceholder={t("filters.location.placeholder")}
data={[...filters.locations]}
filters={
filters?.selectedLocations?.length > 0
? [...filters.selectedLocations]
: []
}
icon={<LocationIcon />}
title={t("filters.location.title")}
setItemsSelected={filters.setSelectedLocations}
/>
);
};

LocationChoser.propTypes = {
filters: PropTypes.any,
};

export default LocationChoser;

+ 5
- 0
src/components/Cards/FilterCard/Choser/LocationChoser/LocationChoser.styled.js Parādīt failu

import styled from "styled-components";
import { ReactComponent as Location } from "../../../../../assets/images/svg/location.svg";

export const LocationIcon = styled(Location)`
`

+ 63
- 0
src/components/Cards/FilterCard/Choser/SubcategoryChoser/SubcategoryChoser.js Parādīt failu

import React, { useEffect, useMemo, useState } from "react";
import PropTypes from "prop-types";
import { SubcategoryIcon } from "./SubcategoryChoser.styled";
import FilterRadioDropdown from "../../FilterDropdown/Radio/FilterRadioDropdown";
import _ from "lodash";
import { useTranslation } from "react-i18next";

const firstSubcategoryOption = {
label: "SVE PODKATEGORIJE",
value: { _id: 0 },
};

const SubcategoryChoser = (props) => {
const filters = props.filters;
const { t } = useTranslation();
const [isOpened, setIsOpened] = useState(false);
const [isDisabled, setIsDisabled] = useState(true);

const setInitialOpen = useMemo(() => {
return _.once(() => {
setIsOpened(true);
});
}, []);

useEffect(() => {
if (!filters.selectedCategory || filters.selectedCategory?._id === 0) {
setIsOpened(false);
setIsDisabled(true);
} else {
setIsDisabled(false);
setInitialOpen();
}
}, [filters.selectedCategory]);

const handleOpen = () => {
setIsOpened((prevState) => !prevState);
};
return (
<FilterRadioDropdown
data={filters.subcategories ? [...filters.subcategories] : []}
icon={<SubcategoryIcon />}
title={
filters.selectedSubcategory?.name
? filters.selectedSubcategory?.name
: t("filters.subcategories.title")
}
searchPlaceholder={t("filters.subcategories.placeholder")}
setSelected={filters.setSelectedSubcategory}
selected={filters.selectedSubcategory}
open={isOpened}
disabled={isDisabled}
handleOpen={handleOpen}
firstOption={firstSubcategoryOption}
/>
);
};

SubcategoryChoser.propTypes = {
filters: PropTypes.any,
};

export default SubcategoryChoser;

+ 4
- 0
src/components/Cards/FilterCard/Choser/SubcategoryChoser/SubcategoryChoser.styled.js Parādīt failu

import styled from "styled-components";
import { ReactComponent as Subcategory } from "../../../../../assets/images/svg/subcategory.svg";

export const SubcategoryIcon = styled(Subcategory)``;

+ 15
- 141
src/components/Cards/FilterCard/FilterCard.js Parādīt failu

import React, { useEffect, useState } from "react";
import React from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import {
ContentContainer,
FilterCardContainer,
Footer,
Header,
Title,
} from "./FilterCard.styled";
import { ReactComponent as Subcategory } from "../../../assets/images/svg/subcategory.svg";
import { ReactComponent as Category } from "../../../assets/images/svg/category.svg";
import { ReactComponent as CategoryChosen } from "../../../assets/images/svg/category-chosen.svg";
import { ReactComponent as Location } from "../../../assets/images/svg/location.svg";
import Link from "../../Link/Link";
import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton";
import FilterCheckboxDropdown from "./FilterDropdown/Checkbox/FilterCheckboxDropdown";
import FilterRadioDropdown from "./FilterDropdown/Radio/FilterRadioDropdown";
import { useTranslation } from "react-i18next";
import selectedTheme from "../../../themes";
import { ContentContainer, FilterCardContainer } from "./FilterCard.styled";
import useFilters from "../../../hooks/useFilters"; import useFilters from "../../../hooks/useFilters";
import HeaderBack from "../../ItemDetails/Header/Header"; import HeaderBack from "../../ItemDetails/Header/Header";
import FilterHeader from "./FilterHeader/FilterHeader";
import FilterFooter from "./FilterFooter/FilterFooter";
import CategoryChoser from "./Choser/CategoryChoser/CategoryChoser";
import SubcategoryChoser from "./Choser/SubcategoryChoser/SubcategoryChoser";
import LocationChoser from "./Choser/LocationChoser/LocationChoser";


const FilterCard = (props) => { const FilterCard = (props) => {
const { t } = useTranslation();
const [isOpened, setIsOpened] = useState(false);
const [isDisabled, setIsDisabled] = useState(true);
const filters = useFilters(props.myOffers); const filters = useFilters(props.myOffers);

useEffect(() => {
if (!filters.selectedCategory || filters.selectedCategory?._id === 0) {
setIsOpened(false);
setIsDisabled(true);
} else {
setIsDisabled(false);
}
}, [filters.selectedCategory]);

const handleSelectCategory = (category) => {
filters.setSelectedCategory(category);
filters.setSelectedSubcategory();
};

const handleOpen = () => {
setIsOpened((prevState) => !prevState);
};

const handleFilters = () => {
filters.applyFilters();
if (props.closeResponsive) props.closeResponsive();
};
const clearFilters = () => {
filters.clearFilters();
};

return ( return (
<FilterCardContainer <FilterCardContainer
responsiveOpen={props.responsiveOpen} responsiveOpen={props.responsiveOpen}
responsive={props.responsive} responsive={props.responsive}
myOffers={props.myOffers} myOffers={props.myOffers}
> >
{/* Header title for my offers */}
{props.myOffers && <HeaderBack />} {props.myOffers && <HeaderBack />}
<Header>
<Title>{t("filters.title")}</Title>
<Link
to="#"
textsize={"12px"}
font={"Open Sans"}
onClick={clearFilters}
>
{t("filters.cancel")}
</Link>
</Header>

<FilterHeader />

<ContentContainer> <ContentContainer>
{/* Categories */} {/* Categories */}
<FilterRadioDropdown
data={[...filters?.categories]}
icon={
filters.selectedCategory?.name ? <CategoryChosen /> : <Category />
}
title={
filters.selectedCategory?.name
? filters.selectedCategory?.name
: t("filters.categories.title")
}
searchPlaceholder={t("filters.categories.placeholder")}
setSelected={handleSelectCategory}
selected={filters.selectedCategory}
firstOption={{
label: "SVE KATEGORIJE",
value: { _id: 0 },
}}
/>
<CategoryChoser filters={filters} />


{/* Subcategories */} {/* Subcategories */}
<FilterRadioDropdown
data={filters.subcategories ? [...filters.subcategories] : []}
icon={<Subcategory />}
title={
filters.selectedSubcategory?.name
? filters.selectedSubcategory?.name
: t("filters.subcategories.title")
}
searchPlaceholder={t("filters.subcategories.placeholder")}
setSelected={filters.setSelectedSubcategory}
selected={filters.selectedSubcategory}
open={isOpened}
disabled={isDisabled}
handleOpen={handleOpen}
firstOption={{
label: "SVE PODKATEGORIJE",
value: { _id: 0 },
}}
/>
<SubcategoryChoser filters={filters} />


{/* Locations */} {/* Locations */}
<FilterCheckboxDropdown
searchPlaceholder={t("filters.location.placeholder")}
data={[...filters.locations]}
filters={
filters?.selectedLocations?.length > 0
? [...filters.selectedLocations]
: []
}
icon={<Location />}
title={t("filters.location.title")}
setItemsSelected={filters.setSelectedLocations}
/>
<LocationChoser filters={filters} />
</ContentContainer> </ContentContainer>


<Footer responsiveOpen={props.responsiveOpen}>
{props.responsiveOpen && (
<PrimaryButton
variant="outlined"
fullWidth
onClick={props.closeResponsive}
textcolor={selectedTheme.primaryPurple}
font="Open Sans"
style={{
fontWeight: "600",
fontSize: "12px",
border: "0",
textAlign: "center",
}}
>
ZATVORI
</PrimaryButton>
)}
<PrimaryButton
variant="outlined"
fullWidth
onClick={handleFilters}
textcolor={selectedTheme.primaryPurple}
font="Open Sans"
style={{
fontWeight: "600",
fontSize: "12px",
borderColor: selectedTheme.primaryPurple,
}}
>
{t("filters.usefilters")}
</PrimaryButton>
</Footer>
<FilterFooter />
</FilterCardContainer> </FilterCardContainer>
); );
}; };

+ 3
- 36
src/components/Cards/FilterCard/FilterCard.styled.js Parādīt failu

import { Box, Typography } from "@mui/material";
import { Box } from "@mui/material";
import styled from "styled-components"; import styled from "styled-components";
import selectedTheme from "../../../themes";


export const FilterCardContainer = styled(Box)` export const FilterCardContainer = styled(Box)`
position: fixed; position: fixed;
margin-top: -14px; margin-top: -14px;
} }
`; `;
export const Title = styled(Typography)`
font-size: 24px;
line-height: 33px;
font-weight: 700;
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
position: relative;
`;
export const Header = styled(Box)`
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
`;

export const Footer = styled(Box)`
position: "sticky";
${(props) =>
props.responsiveOpen &&
`
flex-direction: row;
display: flex;
justify-content: space-around;`}
bottom: 0;
& div button {
height: 48px;
padding-top: 7px;
}
& div button:hover {
background-color: ${selectedTheme.primaryPurple} !important;
color: ${selectedTheme.primaryBackgroundColor} !important;
}
`;
export const ContentContainer = styled(Box)` export const ContentContainer = styled(Box)`
overflow-y: auto; overflow-y: auto;
height: 100%; height: 100%;
scrollbar-color: #ddd; scrollbar-color: #ddd;
${() => window.scrollbars.visible && `padding-right: 15px`}; ${() => window.scrollbars.visible && `padding-right: 15px`};
`; `;



+ 7
- 4
src/components/Cards/FilterCard/FilterDropdown/Radio/FilterRadioDropdown.js Parādīt failu

}, [toSearch]); }, [toSearch]);


useEffect(() => { useEffect(() => {
if (props.selected?._id !== 0 && props.selected !== null && props.selected !== undefined) {
if (
props.selected?._id !== 0 &&
props.selected !== null &&
props.selected !== undefined
) {
setIsOpened(true); setIsOpened(true);
} }
}, [props.selected])

}, [props.selected]);


const handleClear = () => { const handleClear = () => {
setToSearch(""); setToSearch("");
toggleIconClosed={<DropdownDown />} toggleIconClosed={<DropdownDown />}
toggleIconOpened={<DropdownUp />} toggleIconOpened={<DropdownUp />}
fullWidth fullWidth
open={isOpened}
open={ props?.open !== undefined ? props.open : isOpened}
disabled={props.disabled} disabled={props.disabled}
setIsOpened={handleOpen} setIsOpened={handleOpen}
toggleIconStyles={{ toggleIconStyles={{

+ 61
- 0
src/components/Cards/FilterCard/FilterFooter/FilterFooter.js Parādīt failu

import React from "react";
import PropTypes from "prop-types";
import { FilterFooterContainer } from "./FilterFooter.styled";
import selectedTheme from "../../../../themes";
import { PrimaryButton } from "../../../Buttons/PrimaryButton/PrimaryButton";
import { useTranslation } from "react-i18next";
import useFilters from "../../../../hooks/useFilters";

const FilterFooter = (props) => {
const { t } = useTranslation();
const filters = useFilters();
const handleFilters = () => {
filters.applyFilters();
if (props.closeResponsive) props.closeResponsive();
};
return (
<FilterFooterContainer>
{props.responsiveOpen && (
<PrimaryButton
variant="outlined"
fullWidth
onClick={props.closeResponsive}
textcolor={selectedTheme.primaryPurple}
font="Open Sans"
style={{
fontWeight: "600",
fontSize: "12px",
border: "0",
textAlign: "center",
}}
>
{t("common.close")}
</PrimaryButton>
)}
<PrimaryButton
variant="outlined"
fullWidth
onClick={handleFilters}
textcolor={selectedTheme.primaryPurple}
font="Open Sans"
style={{
fontWeight: "600",
fontSize: "12px",
borderColor: selectedTheme.primaryPurple,
}}
>
{t("filters.usefilters")}
</PrimaryButton>
</FilterFooterContainer>
);
};

(FilterFooter.propTypes = {
responsiveOpen: PropTypes.bool,
closeResponsive: PropTypes.func,
}),
(FilterFooter.defaultProps = {
responsiveOpen: false,
});

export default FilterFooter;

+ 22
- 0
src/components/Cards/FilterCard/FilterFooter/FilterFooter.styled.js Parādīt failu

import { Box } from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../../../themes";

export const FilterFooterContainer = styled(Box)`
position: "sticky";
${(props) =>
props.responsiveOpen &&
`
flex-direction: row;
display: flex;
justify-content: space-around;`}
bottom: 0;
& div button {
height: 48px;
padding-top: 7px;
}
& div button:hover {
background-color: ${selectedTheme.primaryPurple} !important;
color: ${selectedTheme.primaryBackgroundColor} !important;
}
`;

+ 28
- 0
src/components/Cards/FilterCard/FilterHeader/FilterHeader.js Parādīt failu

import React from "react";
import PropTypes from "prop-types";
import { FilterHeaderContainer, Title } from "./FilterHeader.styled";
import { useTranslation } from "react-i18next";
import useFilters from "../../../../hooks/useFilters";
import Link from "../../../Link/Link";

const FilterHeader = () => {
const filters = useFilters();
const { t } = useTranslation();
const clearFilters = () => {
filters.clearFilters();
};
return (
<FilterHeaderContainer>
<Title>{t("filters.title")}</Title>
<Link to="#" textsize={"12px"} font={"Open Sans"} onClick={clearFilters}>
{t("filters.cancel")}
</Link>
</FilterHeaderContainer>
);
};

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

export default FilterHeader;

+ 19
- 0
src/components/Cards/FilterCard/FilterHeader/FilterHeader.styled.js Parādīt failu

import { Box, Typography } from "@mui/material";
import styled from "styled-components";
import selectedTheme from "../../../../themes";

export const FilterHeaderContainer = styled(Box)`
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
`;
export const Title = styled(Typography)`
font-size: 24px;
line-height: 33px;
font-weight: 700;
font-family: "Open Sans";
color: ${selectedTheme.primaryText};
position: relative;
`;

+ 0
- 19
src/components/Cards/HomeListCard/HomeListCard.js Parādīt failu

import React from 'react';
//import PropTypes from 'prop-types';
//import SectionLoader from '../Loader/SectionLoader';
import { Box } from '@mui/system';

const HomeListCard = () => {
return (
<Box> Title </Box>
);
};

// AuthCard.propTypes = {
// children: PropTypes.node,
// title: PropTypes.string,
// subtitle: PropTypes.string,
// isLoading: PropTypes.bool,
// };

export default HomeListCard;

+ 29
- 0
src/components/Cards/ItemDetailsCard/Information/Information.js Parādīt failu

import React from "react";
import PropTypes from "prop-types";
import selectedTheme from "../../../../themes";
import { InfoGroup, InfoIcon, InfoText } from "./Information.styled";

const Information = (props) => {
return (
<InfoGroup hide={props.hide}>
<InfoIcon
color={selectedTheme.iconStrokeColor}
component="span"
size="16px"
>
{/* <CategoryIcon width={"14px"} /> */}
{props.icon}
</InfoIcon>
{/* <InfoText>{offer?.offer?.category?.name}</InfoText> */}
<InfoText>{props.value}</InfoText>
</InfoGroup>
);
};

Information.propTypes = {
icon: PropTypes.node,
value: PropTypes.string,
hide: PropTypes.bool,
};

export default Information;

+ 20
- 0
src/components/Cards/ItemDetailsCard/Information/Information.styled.js Parādīt failu

import { Box, Typography } from "@mui/material";
import styled from "styled-components";

export const InfoGroup = styled(Box)`
display: ${props => props.hide ? 'none' : 'flex'};
flex-direction: row;
align-items: center;
gap: 4px;
`;
export const InfoIcon = styled(Box)`
display: flex;
align-items: center;
`;
export const InfoText = styled(Typography)`
font-family: "Open Sans";
text-transform: capitalize;
@media (max-width: 600px) {
font-size: 12px;
}
`;

+ 39
- 110
src/components/Cards/ItemDetailsCard/ItemDetailsCard.js Parādīt failu

import React, { useEffect } from "react";
import React, { useEffect, useMemo } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { import {
CheckButton, CheckButton,
OfferInfo, OfferInfo,
Info, Info,
PostDate, PostDate,
InfoIcon,
InfoText,
InfoGroup,
OfferTitle, OfferTitle,
OfferDescriptionText, OfferDescriptionText,
OfferDescriptionTitle, OfferDescriptionTitle,
OfferDetails, OfferDetails,
OfferImage, OfferImage,
Scroller, Scroller,
CategoryIcon,
SubcategoryIcon,
QuantityIcon,
EyeIcon,
} from "./ItemDetailsCard.styled"; } from "./ItemDetailsCard.styled";
import { ReactComponent as Category } from "../../../assets/images/svg/category.svg";
import { ReactComponent as Subcategory } from "../../../assets/images/svg/subcategory.svg";
import { ReactComponent as Quantity } from "../../../assets/images/svg/quantity.svg";
import { ReactComponent as Eye } from "../../../assets/images/svg/eye-striked.svg";
import selectedTheme from "../../../themes"; import selectedTheme from "../../../themes";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { selectLatestChats } from "../../../store/selectors/chatSelectors"; import { selectLatestChats } from "../../../store/selectors/chatSelectors";
import { useHistory } from "react-router-dom";
import { increaseCounter } from "../../../store/actions/counter/counterActions"; import { increaseCounter } from "../../../store/actions/counter/counterActions";
import _ from "lodash"; import _ from "lodash";
import { selectUserId } from "../../../store/selectors/loginSelectors"; import { selectUserId } from "../../../store/selectors/loginSelectors";
import { formatDateLocale } from "../../../util/helpers/dateHelpers";
import { startChat } from "../../../util/helpers/chatHelper";
import Information from "./Information/Information";
import { useTranslation } from "react-i18next";


const ItemDetailsCard = (props) => { const ItemDetailsCard = (props) => {
const offer = props.offer; const offer = props.offer;
const history = useHistory();
const chats = useSelector(selectLatestChats); const chats = useSelector(selectLatestChats);
const userId = useSelector(selectUserId); const userId = useSelector(selectUserId);
const { t } = useTranslation();
const dispatch = useDispatch(); const dispatch = useDispatch();
const dateCreated = new Date(offer?.offer?._created);

const increaseOfferCounter = useMemo(() => {
return _.once(function (id) {
dispatch(increaseCounter(id));
});
}, []);


useEffect(() => { useEffect(() => {
if (offer?.offer?._id) { if (offer?.offer?._id) {
_.once(function () {
dispatch(increaseCounter(offer?.offer?._id));
})();
increaseOfferCounter(offer?.offer?._id);
} }
}, [offer]); }, [offer]);


const dayCreated =
dateCreated.getDate() < 10
? "0" + dateCreated.getDate()
: dateCreated.getDate();
const monthCreated =
dateCreated.getMonth() < 10
? "0" + (dateCreated.getMonth() + 1)
: dateCreated.getMonth() + 1;
const yearCreated = dateCreated.getFullYear();
const date = formatDateLocale(new Date(offer?.offer?._created));

const startExchange = () => { const startExchange = () => {
const chatItem = chats.find(
(item) => item.chat.offerId === offer?.offer?._id
);
if (chatItem !== undefined) {
history.push(`/messages/${chatItem.chat._id}`);
} else {
if (offer?.offer?.userId !== userId) {
history.push(`/messages/newMessage`, {
offerId: offer?.offer?._id,
});
}
}
startChat(chats, offer, userId);
}; };
return ( return (
<ItemDetailsCardContainer <ItemDetailsCardContainer
> >
<OfferInfo> <OfferInfo>
<Info> <Info>
<InfoGroup>
<InfoIcon
color={selectedTheme.iconStrokeColor}
component="span"
size="16px"
>
<Category width={"14px"} />
</InfoIcon>
<InfoText>{offer?.offer?.category?.name}</InfoText>
</InfoGroup>
<InfoGroup>
<InfoIcon
color={selectedTheme.iconStrokeColor}
component="span"
size="16px"
>
<Subcategory width={"14px"} />
</InfoIcon>
<InfoText>{offer?.offer?.subcategory}</InfoText>
</InfoGroup>
<InfoGroup>
<InfoIcon
color={selectedTheme.iconStrokeColor}
component="span"
size="16px"
>
<Quantity width={"22px"} height={"16px"} />
</InfoIcon>
<InfoText>{offer?.offer?.condition}</InfoText>
</InfoGroup>
{!props.hideViews && (
<InfoGroup views>
<InfoIcon color={"black"} component="span" size="12px" last>
<Eye width={"18px"} height={"20px"} />
</InfoIcon>
<InfoText>{offer?.offer?.views?.count}</InfoText>
</InfoGroup>
)}
<Information
icon={<CategoryIcon />}
value={offer?.offer?.category?.name}
/>
<Information
icon={<SubcategoryIcon />}
value={offer?.offer?.subcategory}
/>
<Information
icon={<QuantityIcon />}
value={offer?.offer?.condition}
/>
<Information icon={<EyeIcon />} value={offer?.offer?.views?.count} />
</Info> </Info>
<PostDate>
{dayCreated}.{monthCreated}.{yearCreated}
</PostDate>
<PostDate>{date}</PostDate>
</OfferInfo> </OfferInfo>
<Details <Details
hasScrollBar={!props.showPublishButton} hasScrollBar={!props.showPublishButton}
})} })}
</Scroller> </Scroller>
<OfferDetails> <OfferDetails>
<OfferDescriptionTitle>Opis:</OfferDescriptionTitle>
<OfferDescriptionTitle>
{t("itemDetailsCard.description")}
</OfferDescriptionTitle>
<OfferDescriptionText showBarterButton={props.showExchangeButton}> <OfferDescriptionText showBarterButton={props.showExchangeButton}>
{offer?.offer?.description} {offer?.offer?.description}
</OfferDescriptionText> </OfferDescriptionText>
</OfferDetails> </OfferDetails>
</Details> </Details>
{!props.halfwidth && props.showExchangeButton ? (
<React.Fragment>
{!props.halfwidth && props.showExchangeButton && (
<CheckButton <CheckButton
variant={props.sponsored ? "contained" : "outlined"} variant={props.sponsored ? "contained" : "outlined"}
buttoncolor={selectedTheme.primaryPurple} buttoncolor={selectedTheme.primaryPurple}
textcolor={props.sponsored ? "white" : selectedTheme.primaryPurple} textcolor={props.sponsored ? "white" : selectedTheme.primaryPurple}
style={{ fontWeight: "600" }}
onClick={startExchange} onClick={startExchange}
> >
Trampi
{t("itemDetailsCard.startExchangeButton")}
</CheckButton> </CheckButton>
</React.Fragment>
) : (
<></>
)} )}
</ItemDetailsCardContainer> </ItemDetailsCardContainer>
); );
}; };


ItemDetailsCard.propTypes = { ItemDetailsCard.propTypes = {
children: PropTypes.node,
id: PropTypes.number,
title: PropTypes.string,
description: PropTypes.string,
category: PropTypes.string,
subcategory: PropTypes.string,
condition: PropTypes.string,
showNumberOfViews: PropTypes.bool,
author: PropTypes.string,
location: PropTypes.string,
images: PropTypes.node,
quantity: PropTypes.number,
package: PropTypes.string,
numberOfViews: PropTypes.number,
halfwidth: PropTypes.bool, halfwidth: PropTypes.bool,
sponsored: PropTypes.bool, sponsored: PropTypes.bool,
offer: PropTypes.any, offer: PropTypes.any,
hideViews: PropTypes.bool, hideViews: PropTypes.bool,
showExchangeButton: PropTypes.bool, showExchangeButton: PropTypes.bool,
// offer: PropTypes.shape({
// images: PropTypes.any,
// name:PropTypes.string,
// description:PropTypes.string,
// condition:PropTypes.string,
// category:PropTypes.shape({
// name:PropTypes.string
// }),
// location:PropTypes.shape({
// city:PropTypes.string
// })
// })
showBarterButton: PropTypes.bool, showBarterButton: PropTypes.bool,
showPublishButton: PropTypes.bool, showPublishButton: PropTypes.bool,
className: PropTypes.string, className: PropTypes.string,

+ 20
- 17
src/components/Cards/ItemDetailsCard/ItemDetailsCard.styled.js Parādīt failu

import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton"; import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton";
import { Icon } from "../../Icon/Icon"; import { Icon } from "../../Icon/Icon";
import HorizontalScroller from "../../Scroller/HorizontalScroller"; import HorizontalScroller from "../../Scroller/HorizontalScroller";
import { ReactComponent as Category } from "../../../assets/images/svg/category.svg";
import { ReactComponent as Subcategory } from "../../../assets/images/svg/subcategory.svg";
import { ReactComponent as Quantity } from "../../../assets/images/svg/quantity.svg";
import { ReactComponent as Eye } from "../../../assets/images/svg/eye-striked.svg";


export const ItemDetailsCardContainer = styled(Container)` export const ItemDetailsCardContainer = styled(Container)`
display: flex; display: flex;
margin: 0; margin: 0;
} }
`; `;
export const InfoGroup = styled(Box)`
display: flex;
flex-direction: row;
align-items: center;
gap: 4px;
`;
export const PostDate = styled(Typography)` export const PostDate = styled(Typography)`
font-family: "Open Sans"; font-family: "Open Sans";
font-size: 12px; font-size: 12px;
left: 5px; left: 5px;
} }
`; `;
export const InfoIcon = styled(Box)`
display: flex;
align-items: center;
`;
export const InfoText = styled(Typography)`
font-family: "Open Sans";
text-transform: capitalize;
@media (max-width: 600px) {
font-size: 12px;
}
`;
export const OfferTitle = styled(Typography)` export const OfferTitle = styled(Typography)`
font-family: "Open Sans"; font-family: "Open Sans";
flex: 1; flex: 1;
position: absolute; position: absolute;
bottom: 9px; bottom: 9px;
right: 12px; right: 12px;
font-weight: 600;
&:hover button { &:hover button {
background-color: ${selectedTheme.primaryPurple} !important; background-color: ${selectedTheme.primaryPurple} !important;
color: white !important; color: white !important;
justify-content: center; justify-content: center;
margin-bottom: 30px; margin-bottom: 30px;
`; `;
export const CategoryIcon = styled(Category)`
width: 14px;
`
export const SubcategoryIcon = styled(Subcategory)`
width: 14px;
`
export const QuantityIcon = styled(Quantity)`
width: 22px;
height: 16px;
`

export const EyeIcon = styled(Eye)`
width: 18px;
height: 20px;
`

+ 14
- 0
src/components/Cards/ItemDetailsCard/OfferDetails/OfferDetails.js Parādīt failu

import React from 'react'
import PropTypes from 'prop-types'

const OfferDetails = () => {
return (
<div>OfferDetails</div>
)
}

OfferDetails.propTypes = {
offer: PropTypes.any,
}

export default OfferDetails

+ 0
- 0
src/components/Cards/ItemDetailsCard/OfferDetails/OfferDetails.styled.js Parādīt failu


+ 2
- 4
src/components/Cards/MiniChatCard/MiniChatCard.js Parādīt failu

const { t } = useTranslation(); const { t } = useTranslation();
const history = useHistory(); const history = useHistory();
const changeChat = () => { const changeChat = () => {
// if (!props.selected) {
history.push(`/messages/${props?.chat?.chat?._id}`)
// }
}
history.push(`/messages/${props?.chat?.chat?._id}`);
};
return ( return (
<MiniChatCardContainer selected={props.selected} onClick={changeChat}> <MiniChatCardContainer selected={props.selected} onClick={changeChat}>
<ProfileImage src={props?.chat?.interlocutorData?.image} /> <ProfileImage src={props?.chat?.interlocutorData?.image} />

+ 5
- 0
src/hooks/useFilters.js Parādīt failu



// Setters // Setters
const setSelectedCategory = (payload) => { const setSelectedCategory = (payload) => {
console.log('payl: ', payload);
if (isApplied !== false) { if (isApplied !== false) {
dispatch(setIsAppliedStatus(false)); dispatch(setIsAppliedStatus(false));
} }
dispatch(setFilteredSubcategory(payload)); dispatch(setFilteredSubcategory(payload));
} }
}; };
const clearSelectedSubcategory = () => {
setSelectedSubcategory();
}
const setSelectedLocations = (payload) => { const setSelectedLocations = (payload) => {
if (isApplied !== false) { if (isApplied !== false) {
dispatch(setIsAppliedStatus(false)); dispatch(setIsAppliedStatus(false));
setSelectedCategory, setSelectedCategory,
selectedSubcategory, selectedSubcategory,
setSelectedSubcategory, setSelectedSubcategory,
clearSelectedSubcategory,
selectedLocations, selectedLocations,
setSelectedLocations, setSelectedLocations,
categories, categories,

+ 5
- 0
src/i18n/resources/rs.js Parādīt failu

miniChatHeaderTitle: "Moje Poruke", miniChatHeaderTitle: "Moje Poruke",
send: "Pošalji", send: "Pošalji",
sendPlaceholder: "Poruka...", sendPlaceholder: "Poruka...",
seeChats: "Pogledaj ćaskanje"
}, },
editProfile: { editProfile: {
website: "Web Sajt*", website: "Web Sajt*",
cancel: "Otkaži", cancel: "Otkaži",
delete: "Obriši", delete: "Obriši",
}, },
itemDetailsCard: {
description: "Opis: ",
startExchangeButton: "Trampi",
}
}; };

+ 0
- 7
src/pages/ErrorPages/NotFoundPage.js Parādīt failu

import React from 'react'; import React from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import Button from '../../components/Buttons/Button';
import Section from '../../components/Section/Section'; import Section from '../../components/Section/Section';


const NotFoundPage = () => { const NotFoundPage = () => {
<div className="c-error-page__content"> <div className="c-error-page__content">
<h1 className="c-error-page__title">404</h1> <h1 className="c-error-page__title">404</h1>
<p className="c-error-page__text">{t('notFound.text')}</p> <p className="c-error-page__text">{t('notFound.text')}</p>
<Button
className="c-error-page__button"
variant="primary-outlined"
>
{t('notFound.goBack')}
</Button>
</div> </div>
</Section> </Section>
</div> </div>

+ 2
- 2
src/request/apiEndpoints.js Parādīt failu

getUserSecurityQuestion: "users/username/securityquestion", getUserSecurityQuestion: "users/username/securityquestion",
confirmSecurityQuestion: "authenticate/confirm", confirmSecurityQuestion: "authenticate/confirm",
confirmForgotPassword: "users/passwords/reset_token", confirmForgotPassword: "users/passwords/reset_token",
resetPassword: "reset-password",
forgotPassword: "forgot-password",
resetPassword: "auth/reset-password",
forgotPassword: "auth/forgot-password",
refreshToken: "/auth/refresh", refreshToken: "/auth/refresh",
generateToken: "/authenticate/generate", generateToken: "/authenticate/generate",
authenticate: authenticate:

+ 1
- 1
src/request/offersRequest.js Parādīt failu

return getRequest(apiEndpoints.offers.getOffers); return getRequest(apiEndpoints.offers.getOffers);
}; };
export const attemptFetchOneOffer = (payload) => { export const attemptFetchOneOffer = (payload) => {
const url = `${apiEndpoints.offers.getOneOffer}/${payload}/frontend`;
const url = `${apiEndpoints.offers.getOneOffer}/${payload}`;
return getRequest(url); return getRequest(url);
} }
export const attemptFetchMoreOffers = (page, payload) => { export const attemptFetchMoreOffers = (page, payload) => {

+ 16
- 0
src/util/helpers/chatHelper.js Parādīt failu

import history from "../../store/utils/history";

export const startChat = (chats, offer, userId) => {
const chatItem = chats.find(
(item) => item.chat.offerId === offer?.offer?._id
);
if (chatItem !== undefined) {
history.push(`/messages/${chatItem.chat._id}`);
} else {
if (offer?.offer?.userId !== userId) {
history.push(`/messages/newMessage`, {
offerId: offer?.offer?._id,
});
}
}
}

+ 13
- 0
src/util/helpers/dateHelpers.js Parādīt failu

const end = formatDate(dates.end); const end = formatDate(dates.end);
return i18next.t('common.date.range', { start, end }); return i18next.t('common.date.range', { start, end });
} }

export function formatDateLocale(date) {
const dayCreated =
date.getDate() < 10
? "0" + date.getDate()
: date.getDate();
const monthCreated =
date.getMonth() < 10
? "0" + (date.getMonth() + 1)
: date.getMonth() + 1;
const yearCreated = date.getFullYear();
return `${dayCreated}.${monthCreated}.${yearCreated}`;
}

Notiek ielāde…
Atcelt
Saglabāt