| @@ -14,7 +14,9 @@ import { | |||
| CREATE_OFFER_PAGE, | |||
| ITEM_DETAILS_PAGE, | |||
| FORGOT_PASSWORD_PAGE, | |||
| PROFILE_PAGE | |||
| PROFILE_PAGE, | |||
| CHAT_MESSAGE_PAGE, | |||
| CHAT_PAGE | |||
| } from './constants/pages'; | |||
| import LoginPage from './pages/LoginPage/LoginPage'; | |||
| import HomePage from './pages/HomePage/HomePageMUI'; | |||
| @@ -29,6 +31,8 @@ import ResetPasswordPage from './pages/ResetPasswordPage/ResetPasswordPage'; | |||
| import CreateOffer from './pages/CreateOffer/CreateOffer'; | |||
| import ItemDetailsPage from './pages/ItemDetailsPage/ItemDetailsPageMUI'; | |||
| import ProfilePage from './pages/ProfilePage/ProfilePage'; | |||
| import ChatMessagesPage from './pages/ChatMessages/ChatMessages'; | |||
| import ChatPage from './pages/Chat/Chat'; | |||
| const AppRoutes = () => { | |||
| @@ -47,6 +51,8 @@ const AppRoutes = () => { | |||
| <Route path={ITEM_DETAILS_PAGE} component={ItemDetailsPage} /> | |||
| <Route path={PROFILE_PAGE} component={ProfilePage} /> | |||
| <Route path={HOME_PAGE} component={HomePage} /> | |||
| <Route path={CHAT_MESSAGE_PAGE} component={ChatMessagesPage} /> | |||
| <Route path={CHAT_PAGE} component={ChatPage} /> | |||
| {/* | |||
| <PrivateRoute | |||
| exact | |||
| @@ -0,0 +1,89 @@ | |||
| import React from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { | |||
| CheckButton, | |||
| MessageIcon, | |||
| OfferAuthor, | |||
| OfferAuthorName, | |||
| OfferImage, | |||
| OfferInfo, | |||
| OfferLocation, | |||
| OfferTitle, | |||
| OfferCard, | |||
| ChatOffer, | |||
| Commands, | |||
| ChatInfo, | |||
| OfferText, | |||
| ChatCardContainer | |||
| } from "./ChatCard.styled"; | |||
| import { ReactComponent as Message } from "../../../assets/images/svg/mail.svg"; | |||
| import selectedTheme from "../../../themes"; | |||
| import { OfferCardContainer } from "../OfferCard/OfferCard.styled"; | |||
| //import { useHistory } from "react-router-dom"; | |||
| const ChatCard = (props) => { | |||
| // const history = useHistory(); | |||
| // const routeToItem = (userId) => { | |||
| // history.push(`/messages/${userId}`); | |||
| // }; | |||
| return ( | |||
| <ChatCardContainer> | |||
| <ChatInfo> | |||
| <OfferTitle>Name</OfferTitle> | |||
| <OfferAuthor> | |||
| <OfferAuthorName >Last chat details</OfferAuthorName> | |||
| <OfferLocation>Location</OfferLocation> | |||
| </OfferAuthor> | |||
| </ChatInfo> | |||
| <OfferInfo> | |||
| <ChatOffer> | |||
| <OfferImage/> | |||
| <OfferCardContainer> | |||
| <OfferText>Proizvod:</OfferText> | |||
| <OfferTitle>Prazne Flase</OfferTitle> | |||
| </OfferCardContainer> | |||
| </ChatOffer> | |||
| </OfferInfo> | |||
| <Commands> | |||
| <MessageIcon vertical={props.vertical}> | |||
| <Message /> | |||
| </MessageIcon> | |||
| <CheckButton | |||
| buttoncolor={selectedTheme.primaryPurple} | |||
| textcolor={"white"} | |||
| style={{ fontWeight: "600" }} | |||
| > | |||
| Pogledaj caskanje | |||
| </CheckButton> | |||
| </Commands> | |||
| </ChatCardContainer> | |||
| ); | |||
| }; | |||
| ChatCard.propTypes = { | |||
| children: PropTypes.node, | |||
| _id: PropTypes.string, | |||
| title: PropTypes.string, | |||
| description: PropTypes.string, | |||
| category: PropTypes.string, | |||
| author: PropTypes.string, | |||
| location: PropTypes.string, | |||
| image: PropTypes.node, | |||
| quantity: PropTypes.number, | |||
| package: PropTypes.string, | |||
| numberOfViews: PropTypes.number, | |||
| halfwidth: PropTypes.bool, | |||
| sponsored: PropTypes.bool, | |||
| offer: PropTypes.any, | |||
| pinned: PropTypes.bool, | |||
| vertical: PropTypes.bool, | |||
| }; | |||
| OfferCard.defaultProps = { | |||
| halfwidth: false, | |||
| sponsored: false, | |||
| }; | |||
| export default ChatCard; | |||
| @@ -0,0 +1,327 @@ | |||
| import { Box, Container, Typography } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import selectedTheme from "../../../themes"; | |||
| import { IconButton } from "../../Buttons/IconButton/IconButton"; | |||
| import { PrimaryButton } from "../../Buttons/PrimaryButton/PrimaryButton"; | |||
| import { Icon } from "../../Icon/Icon"; | |||
| import { ReactComponent as Eye } from "../../../assets/images/svg/eye-striked.svg"; | |||
| export const ChatCardContainer = styled(Container)` | |||
| display: flex; | |||
| flex-direction: column; | |||
| width: ${(props) => (!props.halfwidth ? "100%" : "49%")}; | |||
| box-sizing: border-box; | |||
| margin: 10px 0; | |||
| background-color: ${(props) => | |||
| props.sponsored === "true" | |||
| ? selectedTheme.backgroundSponsoredColor | |||
| : "white"}; | |||
| border-radius: 4px; | |||
| ${(props) => | |||
| props.sponsored === "true" && | |||
| `border: 1px solid ${selectedTheme.borderSponsoredColor};`} | |||
| padding: 16px; | |||
| max-width: 2000px; | |||
| height: 180px; | |||
| position: relative; | |||
| @media (max-width: 550px) { | |||
| height: 184px; | |||
| padding: 18px; | |||
| padding-top: 12px; | |||
| ${(props) => | |||
| props.vertical && | |||
| ` | |||
| height: 330px; | |||
| width: 180px; | |||
| margin: 0 18px; | |||
| `} | |||
| } | |||
| `; | |||
| 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 OfferImage = styled.img` | |||
| max-width: 144px; | |||
| max-height: 144px; | |||
| width: 144px; | |||
| height: 144px; | |||
| @media (max-width: 600px) { | |||
| ${(props) => | |||
| !props.vertical && | |||
| ` | |||
| max-width: 108px; | |||
| max-height: 108px; | |||
| width: 108px; | |||
| height: 108px; | |||
| `} | |||
| } | |||
| `; | |||
| 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)` | |||
| font-family: "Open Sans"; | |||
| flex: 1; | |||
| color: ${selectedTheme.primaryPurple}; | |||
| font-weight: 700; | |||
| font-size: 24px; | |||
| cursor: pointer; | |||
| @media (max-width: 550px) { | |||
| font-size: 18px; | |||
| display: none; | |||
| ${(props) => | |||
| props.vertical && | |||
| ` | |||
| display: flex; | |||
| flex: none; | |||
| position: relative; | |||
| line-height: 22px; | |||
| margin-top: 5px; | |||
| font-size: 18px; | |||
| `} | |||
| } | |||
| `; | |||
| 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 Line = styled(Box)` | |||
| border-left: 1px solid rgba(0, 0, 0, 0.15); | |||
| height: 100px; | |||
| width: 0; | |||
| margin: auto 0; | |||
| @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)` | |||
| width: 180px; | |||
| height: 48px; | |||
| position: absolute; | |||
| bottom: 9px; | |||
| right: 9px; | |||
| &:hover button { | |||
| background-color: ${selectedTheme.primaryPurple} !important; | |||
| color: white !important; | |||
| } | |||
| @media (max-width: 650px) { | |||
| display: none; | |||
| } | |||
| `; | |||
| export const MessageIcon = styled(IconButton)` | |||
| width: 40px; | |||
| height: 40px; | |||
| position: absolute; | |||
| top: 10px; | |||
| right: 10px; | |||
| background-color: ${selectedTheme.primaryIconBackgroundColor}; | |||
| border-radius: 100%; | |||
| padding-top: 2px; | |||
| text-align: center; | |||
| @media (max-width: 600px) { | |||
| width: 30px; | |||
| height: 30px; | |||
| top: 16px; | |||
| right: 16px; | |||
| padding: 0; | |||
| ${(props) => | |||
| props.vertical && | |||
| ` | |||
| display: none; | |||
| `} | |||
| & button svg { | |||
| width: 16px; | |||
| height: 16px; | |||
| position: relative; | |||
| top: -3px; | |||
| left: -2.4px; | |||
| } | |||
| } | |||
| `; | |||
| 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 OfferText = styled(Box)``; | |||
| export const Commands = styled(Box)``; | |||
| export const OfferCard = styled(Box)``; | |||
| export const ChatInfo = styled(Box)``; | |||
| @@ -0,0 +1,19 @@ | |||
| import React from "react"; | |||
| import ChatCard from "../Cards/ChatCard/ChatCard"; | |||
| import Header from "../ItemDetails/Header/Header"; | |||
| import { ChatColumnContainer, ListContainer, ListHeader } from "./ChatColumn.styled"; | |||
| export const ChatColumn = () => { | |||
| return ( | |||
| <ChatColumnContainer> | |||
| <Header /> | |||
| <ListHeader enableSort={true}></ListHeader> | |||
| <ListContainer> | |||
| <ChatCard></ChatCard> | |||
| </ListContainer> | |||
| </ChatColumnContainer> | |||
| ) | |||
| } | |||
| export default ChatColumn; | |||
| @@ -0,0 +1,22 @@ | |||
| import { Box } from "@mui/material"; | |||
| import { Container } from "@mui/system"; | |||
| import styled from "styled-components"; | |||
| export const ChatColumnContainer = styled(Container)` | |||
| `; | |||
| export const ListContainer = styled(Box)` | |||
| display: flex; | |||
| flex-direction: column; | |||
| gap:12px; | |||
| `; | |||
| export const ListHeader = styled(Box)` | |||
| ${(props) => | |||
| props.vertical && | |||
| ` | |||
| position: absolute; | |||
| bottom: 15px; | |||
| `} | |||
| `; | |||
| @@ -11,3 +11,5 @@ export const RESET_PASSWORD_PAGE = "/reset-password/:token"; | |||
| export const CREATE_OFFER_PAGE = "/create-offer"; | |||
| export const ITEM_DETAILS_PAGE = "/proizvodi/:idProizvod"; | |||
| export const PROFILE_PAGE = "/profile/:idProfile" | |||
| export const CHAT_PAGE = "/messages"; | |||
| export const CHAT_MESSAGE_PAGE = "/messages/:idUser"; | |||
| @@ -0,0 +1,27 @@ | |||
| import { ChatGridLayoutContainer } from "./ChatGridLayout.styled" | |||
| export const ChatGridLayout = (props) => { | |||
| return ( | |||
| <ChatGridLayoutContainer> | |||
| {props.children} | |||
| <Grid container maxHeight="xl" spacing={2}> | |||
| <Content item xs={12} lg={9} xl={9.6} md={8} > | |||
| {props.content} | |||
| </Content> | |||
| <RightCard item xs={0} lg={3} xl={2.4} md={4} > | |||
| {props.rightCard} | |||
| </RightCard> | |||
| </Grid> | |||
| </ChatGridLayoutContainer> | |||
| ) | |||
| } | |||
| ChatGridLayout.propTypes = { | |||
| children: PropTypes.node, | |||
| content: PropTypes.node, | |||
| rightCard: PropTypes.node, | |||
| }; | |||
| export default ChatGridLayout | |||
| @@ -0,0 +1,6 @@ | |||
| import { Container } from "@mui/system"; | |||
| import styled from "styled-components"; | |||
| export const ChatGridLayoutContainer = styled(Container)` | |||
| `; | |||
| @@ -0,0 +1,27 @@ | |||
| import React from 'react'; | |||
| import PropTypes from 'prop-types'; | |||
| import { ChatContent, ChatLayoutContainer } from './ChatLayout.styled'; | |||
| import { Grid } from '@mui/material'; | |||
| export const ChatLayout = (props) => { | |||
| return ( | |||
| <ChatLayoutContainer> | |||
| {props.children} | |||
| <Grid container maxHeight="xl" spacing={2}> | |||
| <ChatContent item xs={12} lg={9} xl={9.6} md={8} > | |||
| {props.content} | |||
| </ChatContent> | |||
| </Grid> | |||
| </ChatLayoutContainer> | |||
| ) | |||
| } | |||
| ChatLayout.propTypes = { | |||
| children: PropTypes.node, | |||
| content: PropTypes.node, | |||
| }; | |||
| export default ChatLayout; | |||
| @@ -0,0 +1,9 @@ | |||
| import { Grid } from "@mui/material"; | |||
| import { Container } from "@mui/system"; | |||
| import styled from "styled-components"; | |||
| export const ChatLayoutContainer = styled(Container)` | |||
| `; | |||
| export const ChatContent = styled(Grid)``; | |||
| @@ -0,0 +1,27 @@ | |||
| import React from "react"; | |||
| import { ChatColumn } from "../../components/ChatColumn/ChatColumn"; | |||
| //import PropTypes from 'prop-types'; | |||
| import ChatLayout from "../../layouts/ChatLayout/ChatLayout"; | |||
| import { ChatPageContainer } from "./Chat.styled"; | |||
| export const ChatPage = () => { | |||
| return ( | |||
| <ChatPageContainer> | |||
| <ChatLayout content={<ChatColumn />} /> | |||
| </ChatPageContainer> | |||
| ) | |||
| } | |||
| ChatPage.propTypes = { | |||
| // history: PropTypes.shape({ | |||
| // replace: PropTypes.func, | |||
| // push: PropTypes.func, | |||
| // location: PropTypes.shape({ | |||
| // pathname: PropTypes.string, | |||
| // }), | |||
| // }), | |||
| }; | |||
| export default ChatPage; | |||
| @@ -0,0 +1,16 @@ | |||
| import { Container } from "@mui/system"; | |||
| import styled from "styled-components"; | |||
| export const ChatPageContainer = styled(Container)` | |||
| padding: 0; | |||
| margin: 0; | |||
| margin-top: 80px; | |||
| height: 100%; | |||
| width: 100%; | |||
| max-width: none; | |||
| flex: 1; | |||
| display: flex; | |||
| flex-direction: column; | |||
| `; | |||
| @@ -0,0 +1,22 @@ | |||
| import React from "react"; | |||
| import { ChatMessagesPageContainer } from "./ChatMessages.styled" | |||
| export const ChatMessagesPage = () => { | |||
| return ( | |||
| <ChatMessagesPageContainer> | |||
| </ChatMessagesPageContainer> | |||
| ) | |||
| } | |||
| ChatMessagesPage.propTypes = { | |||
| // history: PropTypes.shape({ | |||
| // replace: PropTypes.func, | |||
| // push: PropTypes.func, | |||
| // location: PropTypes.shape({ | |||
| // pathname: PropTypes.string, | |||
| // }), | |||
| // }), | |||
| }; | |||
| export default ChatMessagesPage; | |||
| @@ -0,0 +1,15 @@ | |||
| import { Container } from "@mui/system"; | |||
| import styled from "styled-components"; | |||
| export const ChatMessagesPageContainer = styled(Container)` | |||
| padding: 0; | |||
| margin: 0; | |||
| margin-top: 80px; | |||
| height: 100%; | |||
| width: 100%; | |||
| max-width: none; | |||
| flex: 1; | |||
| display: flex; | |||
| flex-direction: column; | |||
| `; | |||