| @@ -0,0 +1,3 @@ | |||
| <svg width="72" height="82" viewBox="0 0 72 82" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M55.9821 20.9284C55.9821 32.1726 46.8691 41.2856 35.625 41.2856C24.3809 41.2856 15.2679 32.1726 15.2679 20.9284C15.2679 9.68588 24.3809 0.571289 35.625 0.571289C46.8691 0.571289 55.9821 9.68588 55.9821 20.9284ZM33.2553 57.6985L27.9911 48.9195H43.2589L37.9947 57.6985L43.2907 77.4036L49.5728 51.7663C61.8507 53.6748 71.25 64.2987 71.25 77.1173C71.25 79.8051 69.0552 81.9999 66.3675 81.9999H4.88571C2.1868 81.9999 0 79.8051 0 77.1173C0 64.2987 9.39769 53.6748 21.6772 51.7663L27.9593 77.4036L33.2553 57.6985Z" fill="#D4D4D4"/> | |||
| </svg> | |||
| @@ -43,8 +43,6 @@ const CreateOffer = ({ history }) => { | |||
| const handleMouseDownPassword = () => setShowPassword(!showPassword); | |||
| const categories = useSelector((state) => state.categories.categories); | |||
| console.log(informations); | |||
| // When user refreshes page | |||
| // useEffect(() => { | |||
| // function redirectClient() { | |||
| @@ -123,7 +121,6 @@ const CreateOffer = ({ history }) => { | |||
| const handleSubmitOffer = () => { | |||
| submitOffer(offerData); | |||
| console.log(offerData); | |||
| }; | |||
| return ( | |||
| @@ -4,12 +4,13 @@ import { | |||
| CreateOfferFormContainer, | |||
| FieldLabel, | |||
| Scroller, | |||
| SupportedFormats, | |||
| InputButtonContainer, | |||
| // ImageListStyled, | |||
| } from "./SecondPartCreateOffer.styled"; | |||
| import ImagePicker from "../../../ImagePicker/ImagePicker"; | |||
| // import Select from "../../../Select/Select"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import { useTranslation, Trans } from "react-i18next"; | |||
| import Option from "../../../Select/Option/Option"; | |||
| import { SelectAltText, SelectField, SelectText } from "../CreateOffer.styled"; | |||
| import { NextButton } from "../FirstPart/FirstPartCreateOffer.styled"; | |||
| @@ -59,16 +60,19 @@ const SecondPartCreateOffer = (props) => { | |||
| image={item} | |||
| setImage={(image) => setImage(index, image)} | |||
| deleteImage={() => setImage(index, null)} | |||
| showDeleteIcon | |||
| /> | |||
| ))} | |||
| </Scroller> | |||
| <SupportedFormats> | |||
| <Trans i18nKey="offer.supportedImagesFormats" /> | |||
| </SupportedFormats> | |||
| <InputButtonContainer> | |||
| <FieldLabel leftText={t("offer.condition")} /> | |||
| <SelectField | |||
| defaultValue="default" | |||
| onChange={(value) => { | |||
| formik.setFieldValue("condition", value.target.value); | |||
| console.log(value.target); | |||
| }} | |||
| > | |||
| <Option value="default">{t("offer.choseCondition")}</Option> | |||
| @@ -1,9 +1,8 @@ | |||
| import { Box, ImageList } from "@mui/material"; | |||
| import { Box, Typography } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import selectedTheme from "../../../../themes"; | |||
| import { Label } from "../../../CheckBox/Label"; | |||
| import HorizontalScroller from "../../../Scroller/HorizontalScroller"; | |||
| import { ReactComponent as TrashIcon } from "../../../../assets/images/svg/trash.svg"; | |||
| export const CreateOfferFormContainer = styled(Box)` | |||
| width: 585px; | |||
| @@ -12,19 +11,6 @@ export const CreateOfferFormContainer = styled(Box)` | |||
| margin-top: 20px; | |||
| `; | |||
| export const ImageCard = styled.img` | |||
| width: 216px; | |||
| height: 144px; | |||
| display: flex; | |||
| flex-direction: row; | |||
| flex-wrap: nowrap; | |||
| `; | |||
| export const ImageListStyled = styled(ImageList)` | |||
| display: flex; | |||
| flex: 1; | |||
| overflow: hidden; | |||
| cursor: grab; | |||
| `; | |||
| export const FieldLabel = styled(Label)` | |||
| position: relative; | |||
| top: 12px; | |||
| @@ -52,12 +38,11 @@ export const Scroller = styled(HorizontalScroller)` | |||
| left: calc(-320px + 50%); | |||
| margin-bottom: 36px; | |||
| `; | |||
| export const Trash = styled(TrashIcon)` | |||
| cursor: pointer; | |||
| margin: auto; | |||
| width: 22px; | |||
| height: 22px; | |||
| & path { | |||
| stroke: white; | |||
| } | |||
| export const SupportedFormats = styled(Typography)` | |||
| font-size: 13px; | |||
| width: 100%; | |||
| text-align: center; | |||
| font-family: "Open Sans"; | |||
| margin-top: 25px; | |||
| `; | |||
| @@ -4,11 +4,6 @@ import { CreateOfferFormContainer } from "./ThirdPartCreateOffer.styled"; | |||
| import ItemDetailsCard from "../../ItemDetailsCard/ItemDetailsCard"; | |||
| const ThirdPartCreateOffer = (props) => { | |||
| let date = new Date(); | |||
| let formatedDate = `${date.getDate()}.${ | |||
| date.getMonth() + 1 | |||
| }.${date.getFullYear()}.`; | |||
| const handleSubmit = (e) => { | |||
| e.preventDefault(); | |||
| props.handleSubmitOffer(); | |||
| @@ -21,7 +16,6 @@ const ThirdPartCreateOffer = (props) => { | |||
| subcategory={props.informations.subcategory} | |||
| condition={props.informations.condition} | |||
| showNumberOfViews={false} | |||
| date={formatedDate} | |||
| title={props.informations.nameOfProduct} | |||
| description={props.informations.description} | |||
| images={props.informations.images} | |||
| @@ -74,7 +74,7 @@ const ItemDetailsCard = (props) => { | |||
| </InfoGroup> | |||
| )} | |||
| </Info> | |||
| <PostDate>Objavljeno: {props.date}</PostDate> | |||
| <PostDate>Objavljeno: {offer.postDate}</PostDate> | |||
| </OfferInfo> | |||
| <Details> | |||
| <OfferTitle>{props.title}</OfferTitle> | |||
| @@ -152,7 +152,6 @@ ItemDetailsCard.propTypes = { | |||
| subcategory: PropTypes.string, | |||
| condition: PropTypes.string, | |||
| showNumberOfViews: PropTypes.bool, | |||
| date: PropTypes.string, | |||
| author: PropTypes.string, | |||
| location: PropTypes.string, | |||
| images: PropTypes.node, | |||
| @@ -21,13 +21,6 @@ export const ItemDetailsCardContainer = styled(Container)` | |||
| max-width: 2000px; | |||
| position: relative; | |||
| `; | |||
| export const OfferImage = styled.img` | |||
| width: 144px; | |||
| height: 144px; | |||
| margin-right: 18px; | |||
| object-fit: cover; | |||
| border-radius: 5px; | |||
| `; | |||
| export const OfferInfo = styled(Box)` | |||
| display: flex; | |||
| flex: 2; | |||
| @@ -56,6 +49,7 @@ export const InfoIcon = styled(Box)` | |||
| `; | |||
| export const InfoText = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| text-transform: capitalize; | |||
| `; | |||
| export const OfferTitle = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| @@ -63,7 +57,13 @@ export const OfferTitle = styled(Typography)` | |||
| color: ${selectedTheme.primaryPurple}; | |||
| font-weight: 700; | |||
| font-size: 24px; | |||
| padding: 0 72px; | |||
| padding: 0 60px; | |||
| `; | |||
| export const OfferImage = styled.img` | |||
| width: 144px; | |||
| height: 144px; | |||
| margin-right: 20px; | |||
| object-fit: cover; | |||
| `; | |||
| export const OfferAuthor = styled(Box)` | |||
| display: flex; | |||
| @@ -87,7 +87,7 @@ export const OfferDetails = styled(Box)` | |||
| flex-direction: column; | |||
| flex-wrap: ${(props) => (!props.halfwidth ? "no-wrap" : "wrap")}; | |||
| justify-content: space-between; | |||
| padding: 0 72px; | |||
| padding: 0 60px; | |||
| `; | |||
| export const OfferCategory = styled(Box)` | |||
| font-family: "Open Sans"; | |||
| @@ -1,4 +1,4 @@ | |||
| import React from "react"; | |||
| import React, { useEffect } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { | |||
| CheckButton, | |||
| @@ -27,13 +27,20 @@ import selectedTheme from "../../../themes"; | |||
| import { useHistory } from "react-router-dom"; | |||
| const OfferCard = (props) => { | |||
| const id = 434; | |||
| const history = useHistory(); | |||
| const routeToItem = () => { | |||
| history.push(`/proizvodi/${id}`) | |||
| } | |||
| useEffect(() => { | |||
| console.log(props.offer._id); | |||
| }, []); | |||
| const routeToItem = (itemId) => { | |||
| history.push(`/proizvodi/${itemId}`); | |||
| }; | |||
| return ( | |||
| <OfferCardContainer sponsored={props.offer.pinned.toString()} halfwidth={props.halfwidth ? 1 : 0}> | |||
| <OfferCardContainer | |||
| sponsored={props.offer.pinned.toString()} | |||
| halfwidth={props.halfwidth ? 1 : 0} | |||
| > | |||
| <OfferImage src={props.offer.images[0]}></OfferImage> | |||
| <OfferInfo> | |||
| <OfferTitle>{props.offer.name}</OfferTitle> | |||
| @@ -58,18 +65,20 @@ const OfferCard = (props) => { | |||
| </OfferInfo> | |||
| {!props.halfwidth ? ( | |||
| <React.Fragment> | |||
| <Line/> | |||
| <Line /> | |||
| <OfferDescription> | |||
| <OfferDescriptionTitle>Opis:</OfferDescriptionTitle> | |||
| <OfferDescriptionText>{props.offer.description}</OfferDescriptionText> | |||
| <OfferDescriptionText> | |||
| {props.offer.description} | |||
| </OfferDescriptionText> | |||
| </OfferDescription> | |||
| <CheckButton | |||
| variant={props.sponsored ? "contained" : "outlined"} | |||
| buttoncolor={selectedTheme.primaryPurple} | |||
| textcolor={props.sponsored ? "white" : selectedTheme.primaryPurple} | |||
| style={{fontWeight: "600"}} | |||
| onClick = {routeToItem} | |||
| style={{ fontWeight: "600" }} | |||
| onClick={() => routeToItem(props.offer._id)} | |||
| > | |||
| Pogledaj proizvod | |||
| </CheckButton> | |||
| @@ -97,7 +106,7 @@ const OfferCard = (props) => { | |||
| OfferCard.propTypes = { | |||
| children: PropTypes.node, | |||
| id: PropTypes.number, | |||
| _id: PropTypes.string, | |||
| title: PropTypes.string, | |||
| description: PropTypes.string, | |||
| category: PropTypes.string, | |||
| @@ -1,100 +1,92 @@ | |||
| import React, { useRef, useState } from "react"; | |||
| import React, { useEffect, useRef, useState } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { | |||
| AddFile, | |||
| AddIcon, | |||
| ImageOverlay, | |||
| ImagePickerContainer, | |||
| ImageUploaded, | |||
| Tools, | |||
| } from "./ImagePicker.styled"; | |||
| import { Tooltip } from "@mui/material"; | |||
| import { Trash } from "../Cards/CreateOfferCard/SecondPart/SecondPartCreateOffer.styled"; | |||
| import { Icon } from "../Icon/Icon"; | |||
| import { IconButton } from "../Buttons/IconButton/IconButton"; | |||
| import { ReactComponent as EditIcon } from "../../assets/images/svg/edit.svg"; | |||
| import { ReactComponent as TrashIcon } from "../../assets/images/svg/trash.svg"; | |||
| // import { Input } from "@mui/material"; | |||
| const ImagePicker = (props) => { | |||
| const fileInputRef = useRef(null); | |||
| const [isOpened, setIsOpened] = useState(false); | |||
| const imageRef = useRef(null); | |||
| const [image, setImage] = useState(""); | |||
| const [isEditing, setIsEditing] = useState(false); | |||
| let listener; | |||
| useEffect(() => { | |||
| listener = (event) => { | |||
| if (imageRef.current) { | |||
| if (imageRef.current.contains(event.target)) { | |||
| setIsEditing(true); | |||
| } else { | |||
| setIsEditing(false); | |||
| } | |||
| } | |||
| }; | |||
| window.addEventListener("click", listener); | |||
| return () => window.removeEventListener("click", listener); | |||
| }, [imageRef]); | |||
| const handleChange = () => { | |||
| fileInputRef.current.value = ""; | |||
| fileInputRef.current.click(); | |||
| console.log(fileInputRef.current.click); | |||
| }; | |||
| const handleImage = (event) => { | |||
| console.log("fileEvent: ", event.target.files[0]); | |||
| let reader = new FileReader(); | |||
| reader.readAsDataURL(event.target.files[0]); | |||
| reader.onload = () => { | |||
| console.log(reader.result.toString()); | |||
| props.setImage(reader.result); | |||
| if (props.setImage) props.setImage(reader.result); | |||
| setImage(reader.result); | |||
| }; | |||
| reader.onerror = (error) => { | |||
| console.log(error); | |||
| }; | |||
| reader.onerror = () => {}; | |||
| }; | |||
| // let timeoutObject = { | |||
| // timeoutFunctionSet: false, | |||
| // timeoutFunction: () => {}, | |||
| // }; | |||
| // const showMessage = (event) => { | |||
| // console.log(event); | |||
| // }; | |||
| // const handleMouseEnter = (event) => { | |||
| // timeoutObject.timeoutFunctionSet = true; | |||
| // timeoutObject.timeoutFunction = setTimeout(() => { | |||
| // showMessage(event); | |||
| // }, 1000); | |||
| // }; | |||
| // const handleMouseMove = (event) => { | |||
| // if (timeoutObject.timeoutFunctionSet) { | |||
| // clearTimeout(timeoutObject.timeoutFunction); | |||
| // timeoutObject.timeoutFunction = setTimeout(() => { | |||
| // showMessage(event); | |||
| // }, 1000); | |||
| // } | |||
| // }; | |||
| // const handleMouseLeave = () => { | |||
| // if (timeoutObject.timeoutFunctionSet) { | |||
| // clearTimeout(timeoutObject.timeoutFunction); | |||
| // timeoutObject.timeoutFunctionSet = false; | |||
| // } | |||
| // }; | |||
| const handleOpen = () => { | |||
| setIsOpened(true); | |||
| if (!props.image) setIsOpened(false); | |||
| }; | |||
| const handleClose = () => { | |||
| setIsOpened(false); | |||
| }; | |||
| const handleDelete = () => { | |||
| props.deleteImage(); | |||
| setIsOpened(false) | |||
| } | |||
| if (props.deleteImage) props.deleteImage(); | |||
| setImage(""); | |||
| setIsEditing(false); | |||
| }; | |||
| return ( | |||
| <Tooltip | |||
| open={isOpened} | |||
| onOpen={handleOpen} | |||
| onClose={handleClose} | |||
| enterDelay={500} | |||
| enterNextDelay={500} | |||
| arrow | |||
| title={ | |||
| <Icon style={{width: "50px", height: "42px", paddingTop: "10px"}}> | |||
| <Trash onClick={handleDelete} /> | |||
| </Icon> | |||
| } | |||
| d | |||
| <ImagePickerContainer | |||
| className={props.className} | |||
| onClick={!image ? handleChange : () => {}} | |||
| hasImage={props.image} | |||
| > | |||
| <ImagePickerContainer | |||
| className={props.className} | |||
| onClick={!props.image ? handleChange : () => {}} | |||
| hasImage={props.image} | |||
| > | |||
| <AddFile type="file" ref={fileInputRef} onInput={handleImage} /> | |||
| {props.image ? ( | |||
| <ImageUploaded src={props.image} draggable={false}></ImageUploaded> | |||
| ) : ( | |||
| <AddIcon /> | |||
| )} | |||
| </ImagePickerContainer> | |||
| </Tooltip> | |||
| <AddFile type="file" ref={fileInputRef} onInput={handleImage} /> | |||
| {image ? ( | |||
| <React.Fragment> | |||
| <ImageUploaded src={image} draggable={false} ref={imageRef} /> | |||
| {isEditing && ( | |||
| <React.Fragment> | |||
| <ImageOverlay /> | |||
| <Tools showDeleteIcon={props.showDeleteIcon}> | |||
| <IconButton onClick={handleChange}> | |||
| <EditIcon /> | |||
| </IconButton> | |||
| {props.showDeleteIcon && ( | |||
| <IconButton onClick={handleDelete}> | |||
| <TrashIcon /> | |||
| </IconButton> | |||
| )} | |||
| </Tools> | |||
| </React.Fragment> | |||
| )} | |||
| </React.Fragment> | |||
| ) : ( | |||
| <AddIcon /> | |||
| )} | |||
| {props.children} | |||
| </ImagePickerContainer> | |||
| ); | |||
| }; | |||
| @@ -103,7 +95,8 @@ ImagePicker.propTypes = { | |||
| className: PropTypes.string, | |||
| setImage: PropTypes.func, | |||
| image: PropTypes.func, | |||
| deleteImage: PropTypes.func | |||
| deleteImage: PropTypes.func, | |||
| showDeleteIcon: PropTypes.bool, | |||
| }; | |||
| export default ImagePicker; | |||
| @@ -2,6 +2,7 @@ import { Box } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import selectedTheme from "../../themes"; | |||
| import { ReactComponent as Plus } from "../../assets/images/svg/plus.svg"; | |||
| import { ReactComponent as TrashIcon } from "../../assets/images/svg/trash.svg"; | |||
| export const ImagePickerContainer = styled(Box)` | |||
| flex: 1; | |||
| @@ -10,8 +11,10 @@ export const ImagePickerContainer = styled(Box)` | |||
| flex-grow: 0; | |||
| flex-shrink: 0; | |||
| height: 144px; | |||
| width: 144px; | |||
| margin: 0 9px; | |||
| border-radius: 4px; | |||
| position: relative; | |||
| cursor: pointer; | |||
| background-color: ${selectedTheme.imagePickerBackground}; | |||
| background-image: linear-gradient( | |||
| @@ -50,6 +53,9 @@ export const ImagePickerContainer = styled(Box)` | |||
| `; | |||
| export const AddIcon = styled(Plus)` | |||
| margin: auto; | |||
| z-index: 1; | |||
| width: 60px; | |||
| height: 60px; | |||
| `; | |||
| export const AddFile = styled.input` | |||
| display: none; | |||
| @@ -57,7 +63,20 @@ export const AddFile = styled.input` | |||
| export const ImageUploaded = styled.img` | |||
| width: 144px; | |||
| height: 144px; | |||
| /* border-radius: 100px; */ | |||
| /* object-fit: scale-down; */ | |||
| object-fit: cover; | |||
| z-index: 1; | |||
| `; | |||
| export const ImageOverlay = styled(Box)` | |||
| position: absolute; | |||
| top: 0; | |||
| left: 0; | |||
| width: 100%; | |||
| height: 100%; | |||
| background-color: rgba(0, 0, 0, 0.5); | |||
| z-index: 3; | |||
| overflow: hidden; | |||
| `; | |||
| export const Tooltip = styled(Box)` | |||
| background-color: rgba(255, 255, 255, 0.5); | |||
| @@ -67,3 +86,27 @@ export const Tooltip = styled(Box)` | |||
| left: 0; | |||
| top: 0; | |||
| `; | |||
| export const Trash = styled(TrashIcon)` | |||
| cursor: pointer; | |||
| margin: auto; | |||
| width: 22px; | |||
| height: 22px; | |||
| & path { | |||
| stroke: white; | |||
| } | |||
| `; | |||
| export const Tools = styled(Box)` | |||
| position: absolute; | |||
| padding-top: 44px; | |||
| padding-left: ${(props) => (props.showDeleteIcon ? "16px" : "45px")}; | |||
| z-index: 4; | |||
| flex-direction: row; | |||
| display: flex; | |||
| & div { | |||
| background-color: ${selectedTheme.primaryIconBackgroundColor}; | |||
| border-radius: 100px; | |||
| display: flex; | |||
| flex: 1; | |||
| margin: 10px; | |||
| } | |||
| `; | |||
| @@ -1,19 +1,21 @@ | |||
| import React from 'react'; | |||
| import React from "react"; | |||
| import Header from "./Header/Header"; | |||
| import { ItemDetailsContainer } from './ItemDetails.styled'; | |||
| import { useSelector } from "react-redux"; | |||
| import { ItemDetailsContainer } from "./ItemDetails.styled"; | |||
| import ItemDetailsCard from "../Cards/ItemDetailsCard/ItemDetailsCard"; | |||
| import ItemDetailsHeaderCard from "./ItemDetailsHeaderCard/ItemDetailsHeaderCard"; | |||
| import { selectOffer } from "../../store/selectors/offersSelectors"; | |||
| const ItemDetails = () => { | |||
| return ( | |||
| <ItemDetailsContainer> | |||
| <Header/> | |||
| <ItemDetailsHeaderCard /> | |||
| <ItemDetailsCard/> | |||
| </ItemDetailsContainer> | |||
| ) | |||
| } | |||
| const offer = useSelector(selectOffer); | |||
| return ( | |||
| <ItemDetailsContainer> | |||
| <Header /> | |||
| <ItemDetailsHeaderCard offer={offer} /> | |||
| <ItemDetailsCard offer={offer} /> | |||
| </ItemDetailsContainer> | |||
| ); | |||
| }; | |||
| export default ItemDetails; | |||
| export default ItemDetails; | |||
| @@ -11,43 +11,54 @@ import { | |||
| HeaderTop, | |||
| HeaderDetails, | |||
| BottomDetails, | |||
| StatusText | |||
| StatusText, | |||
| } from "./ItemDetailsHeaderCard.styled"; | |||
| import { ItemDetailsHeaderContainer } from "./ItemDetailsHeaderCard.styled"; | |||
| import { ReactComponent as Category } from "../../../assets/images/svg/category.svg"; | |||
| //import { ReactComponent as Quantity } from "../../../assets/images/svg/quantity.svg"; | |||
| //import { ReactComponent as Eye } from "../../../assets/images/svg/eye-striked.svg"; | |||
| import { ReactComponent as PIB} from "../../../assets/images/svg/pib.svg"; | |||
| import { ReactComponent as PIB } from "../../../assets/images/svg/pib.svg"; | |||
| import { ReactComponent as MessageColor } from "../../../assets/images/svg/mailColor.svg"; | |||
| import selectedTheme from "../../../themes"; | |||
| import { Author as author } from "../MockupdataDetails"; | |||
| const ItemDetailsHeaderCard = (props) => { | |||
| return ( | |||
| <ItemDetailsHeaderContainer sponsored={props.sponsored.toString()} halfwidth={props.halfwidth ? 1 : 0}> | |||
| <ItemDetailsHeaderContainer | |||
| sponsored={props.sponsored.toString()} | |||
| halfwidth={props.halfwidth ? 1 : 0} | |||
| > | |||
| <HeaderTop> | |||
| <OfferImage>{author.image}</OfferImage> | |||
| <OfferImage>{author.image}</OfferImage> | |||
| <OfferDetails> | |||
| <OfferTitle>{author.title}</OfferTitle> | |||
| <DetailContainer> | |||
| <DetailIcon color={selectedTheme.iconStrokeColor} component="span" size="22px"> | |||
| <OfferTitle>{author.title}</OfferTitle> | |||
| <DetailContainer> | |||
| <DetailIcon | |||
| color={selectedTheme.iconStrokeColor} | |||
| component="span" | |||
| size="22px" | |||
| > | |||
| <PIB width={"22px"} /> | |||
| </DetailIcon> | |||
| <DetailText>PIB - {author.pib}</DetailText> | |||
| </DetailContainer> | |||
| <DetailContainer> | |||
| <DetailIcon color={selectedTheme.iconStrokeColor} component="span" size="22px"> | |||
| <DetailText>PIB - {author.pib}</DetailText> | |||
| </DetailContainer> | |||
| <DetailContainer> | |||
| <DetailIcon | |||
| color={selectedTheme.iconStrokeColor} | |||
| component="span" | |||
| size="22px" | |||
| > | |||
| <Category width={"22px"} /> | |||
| </DetailIcon> | |||
| <DetailText>{author.location}</DetailText> | |||
| </DetailContainer> | |||
| </OfferDetails> | |||
| <DetailText>{author.location}</DetailText> | |||
| </DetailContainer> | |||
| </OfferDetails> | |||
| <MessageIcon> | |||
| <MessageColor /> | |||
| <MessageColor /> | |||
| </MessageIcon> | |||
| </HeaderTop> | |||
| <HeaderDetails> | |||
| <BottomDetails> | |||
| <BottomDetails> | |||
| <StatusText> | |||
| <b>{author.numberOfOffers}</b> objava | |||
| </StatusText> | |||
| @@ -62,7 +73,6 @@ const ItemDetailsHeaderCard = (props) => { | |||
| </StatusText> | |||
| </BottomDetails> | |||
| </HeaderDetails> | |||
| </ItemDetailsHeaderContainer> | |||
| ); | |||
| }; | |||
| @@ -81,6 +91,18 @@ ItemDetailsHeaderCard.propTypes = { | |||
| numberOfViews: PropTypes.number, | |||
| halfwidth: PropTypes.bool, | |||
| sponsored: PropTypes.bool, | |||
| offer: PropTypes.shape({ | |||
| images: PropTypes.any, | |||
| name: PropTypes.string, | |||
| description: PropTypes.string, | |||
| category: PropTypes.shape({ | |||
| name: PropTypes.string, | |||
| }), | |||
| location: PropTypes.shape({ | |||
| city: PropTypes.string, | |||
| }), | |||
| }), | |||
| }; | |||
| ItemDetailsHeaderCard.defaultProps = { | |||
| halfwidth: false, | |||
| @@ -16,7 +16,7 @@ import Mockupdata from "./Mockupdata"; | |||
| import ThumbUpIcon from "@mui/icons-material/ThumbUp"; | |||
| import ThumbDownIcon from "@mui/icons-material/ThumbDown"; | |||
| import StarBorderIcon from "@mui/icons-material/StarBorder"; | |||
| import { PRIMARY_PURPLE_COLOR } from "../../constants/stylesConstants"; | |||
| import selectedTheme from "../../themes"; | |||
| const UserReviewsCard = (props) => { | |||
| var dataMockupdata = JSON.parse(JSON.stringify(Mockupdata)); | |||
| @@ -44,7 +44,7 @@ const UserReviewsCard = (props) => { | |||
| <ListItemAvatar sx={{ mt: 0 }}> | |||
| <Avatar alt={review.name} src="/static/images/avatar/1.jpg" /> | |||
| </ListItemAvatar> | |||
| <Typography sx={{ color: PRIMARY_PURPLE_COLOR }}> | |||
| <Typography sx={{ color: selectedTheme.primaryPurple }}> | |||
| <b>{review.name}</b> | |||
| </Typography> | |||
| </ListItem> | |||
| @@ -4,10 +4,6 @@ import { List, Box } from "@mui/material"; | |||
| export const ReviewsBox = styledComponents(Box)` | |||
| width: 100%; | |||
| max-width: 360px; | |||
| position: fixed; | |||
| right: 0; | |||
| bottom: 0; | |||
| height: calc(100% - 90px); | |||
| `; | |||
| @@ -92,6 +92,7 @@ export default { | |||
| PIBTaken: "PIB je zauzet!", | |||
| PIBnoOfCharacters: "PIB mora imati 9 karaktera!", | |||
| welcome: "Dobro došli na trampu, želimo vam uspešno trampovanje!", | |||
| imageError: "Slika je obavezna!", | |||
| }, | |||
| forgotPassword: { | |||
| title: "Povrati lozinku", | |||
| @@ -151,5 +152,7 @@ export default { | |||
| choseSubcategory: "Izaberi podkategoriju", | |||
| condition: "STANJE", | |||
| choseCondition: "Izaberi Stanje", | |||
| supportedImagesFormats: | |||
| "Podržani formati fotografija: <strong>.JPG</strong> | <strong>.PNG</strong>", | |||
| }, | |||
| }; | |||
| @@ -1,20 +1,23 @@ | |||
| import React from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { Content, RightCard, ItemDetailsLayoutContainer } from "./ItemDetailsLayout.styled"; | |||
| import { | |||
| Content, | |||
| RightCard, | |||
| ItemDetailsLayoutContainer, | |||
| } from "./ItemDetailsLayout.styled"; | |||
| import { Grid } from "@mui/material"; | |||
| const ItemDetailsLayout = (props) => { | |||
| return ( | |||
| <ItemDetailsLayoutContainer> | |||
| {props.children} | |||
| <Grid container maxHeight="xl"> | |||
| <Content item xs={10} lg={9} xl={9.6} md={8} > | |||
| <Grid container maxHeight="xl" spacing={2}> | |||
| <Content item xs={10} lg={9} xl={9.6} md={8}> | |||
| {props.content} | |||
| </Content> | |||
| <RightCard item xs={2} lg={3} xl={2.4} md={4} > | |||
| <RightCard item xs={2} lg={3} xl={2.4} md={4}> | |||
| {props.rightCard} | |||
| </RightCard> | |||
| </Grid> | |||
| </ItemDetailsLayoutContainer> | |||
| ); | |||
| @@ -51,4 +51,20 @@ export const ErrorMessage = styled(Typography)` | |||
| position: relative; | |||
| top: -7px; | |||
| font-size: 14px; | |||
| ` | |||
| ` | |||
| export const LoginAltText = styled(Typography)` | |||
| font-family: "Poppins"; | |||
| color: ${selectedTheme.primaryText}; | |||
| font-size: 14px; | |||
| padding-right: 6px; | |||
| line-height: 14px; | |||
| `; | |||
| export const LoginTextContainer = styled(Box)` | |||
| display: flex; | |||
| flex-direction: row; | |||
| margin-top: 36px; | |||
| justify-content: center; | |||
| @media (max-height: 800px) { | |||
| margin-top: 26px; | |||
| } | |||
| `; | |||
| @@ -28,7 +28,11 @@ const MailSent = () => { | |||
| const dispatch = useDispatch(); | |||
| useEffect(() => { | |||
| setEmail(location.state.email); | |||
| if (location.state.email) { | |||
| setEmail(location.state.email); | |||
| } else { | |||
| history.push("/login"); | |||
| } | |||
| }, []); | |||
| const navigateLogin = () => { | |||
| @@ -1,7 +1,6 @@ | |||
| import React, { useState } from "react"; | |||
| import { useFormik } from "formik"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import * as Yup from "yup"; | |||
| // import i18next from "i18next"; | |||
| import { ReactComponent as Logo } from "../../assets/images/svg/logo-vertical.svg"; | |||
| import { | |||
| @@ -10,14 +9,19 @@ import { | |||
| ForgotPasswordTitle, | |||
| FormContainer, | |||
| ErrorMessage, | |||
| LoginTextContainer, | |||
| LoginAltText, | |||
| } from "./ForgotPassword.styled"; | |||
| import { TextField } from "../../components/TextFields/TextField/TextField"; | |||
| import { PrimaryButton } from "../../components/Buttons/PrimaryButton/PrimaryButton"; | |||
| import { useHistory } from "react-router-dom"; | |||
| import { NavLink, useHistory } from "react-router-dom"; | |||
| import { FORGOT_PASSWORD_MAIL_SENT } from "../../constants/pages"; | |||
| import selectedTheme from "../../themes"; | |||
| import { useDispatch } from "react-redux"; | |||
| import { forgotPassword } from "../../store/actions/user/userActions"; | |||
| import forgotPasswordValidation from "../../validations/forgotPasswordValidation"; | |||
| import forgotPasswordInitialValues from "../../initialValues/forgotPasswordInitialValues"; | |||
| import Link from "../../components/Link/Link"; | |||
| const ForgotPasswordPage = () => { | |||
| const history = useHistory(); | |||
| @@ -25,12 +29,6 @@ const ForgotPasswordPage = () => { | |||
| const dispatch = useDispatch(); | |||
| const [emailNotFoundStatus, setEmailNotFoundStatus] = useState(false); | |||
| const forgotPasswordValidationSchema = Yup.object().shape({ | |||
| email: Yup.string() | |||
| .required(t("forgotPassword.emailRequired")) | |||
| .email(t("forgotPassword.emailFormat")), | |||
| }); | |||
| const handleResponseSuccess = () => { | |||
| history.push({ | |||
| pathname: FORGOT_PASSWORD_MAIL_SENT, | |||
| @@ -52,10 +50,8 @@ const ForgotPasswordPage = () => { | |||
| }; | |||
| const formik = useFormik({ | |||
| initialValues: { | |||
| email: "", | |||
| }, | |||
| validationSchema: forgotPasswordValidationSchema, | |||
| initialValues: forgotPasswordInitialValues, | |||
| validationSchema: forgotPasswordValidation, | |||
| onSubmit: handleSubmit, | |||
| validateOnBlur: true, | |||
| enableReinitialize: true, | |||
| @@ -109,6 +105,19 @@ const ForgotPasswordPage = () => { | |||
| > | |||
| {t("common.send")} | |||
| </PrimaryButton> | |||
| <LoginTextContainer> | |||
| <LoginAltText>{t("register.loginText")}</LoginAltText> | |||
| <Link | |||
| to="/login" | |||
| component={NavLink} | |||
| underline="hover" | |||
| align="center" | |||
| > | |||
| {t("register.login")} | |||
| </Link> | |||
| </LoginTextContainer> | |||
| </FormContainer> | |||
| </ForgotPasswordPageContainer> | |||
| ); | |||
| @@ -1,60 +1,42 @@ | |||
| import React, { useEffect } from "react"; | |||
| import { PropTypes } from "prop-types"; | |||
| import Navbar from "../../components/MUI/NavbarComponent"; | |||
| import { ItemDetailsPageContainer } from "./ItemDetailsPage.styled"; | |||
| import { useDispatch } from "react-redux"; | |||
| import { logoutUser } from "../../store/actions/login/loginActions"; | |||
| import Mockupdata from "../../components/Cards/FilterCard/Mockupdata"; | |||
| import qs from "query-string"; | |||
| import { useHistory } from "react-router-dom"; | |||
| import { setFilters } from "../../store/actions/filters/filtersActions"; | |||
| import { useDispatch, useSelector } from "react-redux"; | |||
| import ItemDetails from "../../components/ItemDetails/ItemDetails"; | |||
| import ItemDetailsLayout from "../../layouts/ItemDetailsLayout/ItemDetailsLayout"; | |||
| import UserReviewsCard from "../../components/UserReviewsCard/UserReviewsCard"; | |||
| import { fetchOneOffer } from "../../store/actions/offers/offersActions"; | |||
| import { selectOffer } from "../../store/selectors/offersSelectors"; | |||
| const ItemDetailsPage = () => { | |||
| const ItemDetailsPage = (props) => { | |||
| const dispatch = useDispatch(); | |||
| const offer = useSelector(selectOffer); | |||
| //const routetMatch = useRouteMatch(); | |||
| const history = useHistory(); | |||
| const offerId = props.match.params.idProizvod; | |||
| useEffect(() => { | |||
| const queryString = history.location.search.substring(1); | |||
| const queryObject = qs.parse(queryString); | |||
| let category = null; | |||
| if (queryObject.category) { | |||
| category = Mockupdata[1].find( | |||
| (item) => item.string === queryObject.category.toString() | |||
| ).id; | |||
| } | |||
| let cities = []; | |||
| if (queryObject.city) { | |||
| if (Array.isArray(queryObject.city)) { | |||
| queryObject.city.forEach((item) => { | |||
| cities.push(Mockupdata[0].find((p) => p.string === item).id); | |||
| }); | |||
| } else { | |||
| cities.push( | |||
| Mockupdata[0].find((p) => p.string === queryObject.city).id | |||
| ); | |||
| } | |||
| } | |||
| let subcategory = null; | |||
| if (queryObject.subcategory) { | |||
| subcategory = Mockupdata[1].find( | |||
| (item) => item.string === queryObject.subcategory.toString() | |||
| ).id; | |||
| dispatch(fetchOneOffer(offerId)); | |||
| }, [offerId]); | |||
| useEffect(() => { | |||
| if ( | |||
| typeof offer !== "undefined" && | |||
| typeof offer.userId !== "undefined" && | |||
| offer.userId !== "" | |||
| ) { | |||
| console.log(offer.userId); | |||
| } | |||
| console.log("iz useeffect: ", { category, subcategory, cities }); | |||
| dispatch(setFilters({ category, subcategory, cities })); | |||
| }, [history.location.search]); | |||
| const handleCl = () => { | |||
| dispatch(logoutUser()); | |||
| }; | |||
| }, [offer]); | |||
| return ( | |||
| <ItemDetailsPageContainer> | |||
| <button onClick={handleCl}>Dugme</button> | |||
| <Navbar /> | |||
| {/* right card mora mi bude Review Card */} | |||
| <ItemDetailsLayout content={<ItemDetails />} /> | |||
| <ItemDetailsLayout | |||
| content={<ItemDetails />} | |||
| rightCard={<UserReviewsCard />} | |||
| /> | |||
| {/* <Box sx={{ mt: 4, mx: 4 }}> | |||
| <GridStyled container justifyContent="space-between"> | |||
| @@ -81,4 +63,12 @@ const ItemDetailsPage = () => { | |||
| ); | |||
| }; | |||
| ItemDetailsPage.propTypes = { | |||
| match: PropTypes.shape({ | |||
| params: PropTypes.shape({ | |||
| idProizvod: PropTypes.string, | |||
| }), | |||
| }), | |||
| }; | |||
| export default ItemDetailsPage; | |||
| @@ -83,7 +83,7 @@ const FirstPartOfRegistration = (props) => { | |||
| InputProps={{ | |||
| endAdornment: ( | |||
| <IconButton onClick={handleClickShowPassword}> | |||
| {showPassword ? <VisibilityOn /> : <VisibilityOff />} | |||
| {showPassword ? <VisibilityOff /> : <VisibilityOn />} | |||
| </IconButton> | |||
| ), | |||
| }} | |||
| @@ -9,6 +9,10 @@ import { | |||
| ProgressContainer, | |||
| RegisterDescription, | |||
| RegisterTitle, | |||
| ProfileImagePicker, | |||
| ProfilePicture, | |||
| RegisterPageContent, | |||
| ErrorMessage, | |||
| } from "./Register.styled"; | |||
| import { ReactComponent as Logo } from "../../../assets/images/svg/logo-vertical.svg"; | |||
| import { NavLink, useHistory } from "react-router-dom"; | |||
| @@ -28,19 +32,21 @@ const Register = () => { | |||
| const dispatch = useDispatch(); | |||
| const [currentStep, setCurrentStep] = useState(1); | |||
| const [informations, setInformations] = useState({}); // Values of fields typed in all steps | |||
| const [mailError, setMailError] = useState(""); // Wrong mail typed | |||
| const [mailErrorMessage, setMailErrorMessage] = useState(""); // Error message caused by typing wrong mail | |||
| const [PIBError, setPIBError] = useState(""); // Wrong PIB typed | |||
| const [PIBErrorMessage, setPIBErrorMessage] = useState(""); // Error message caused by typing wrong PIB | |||
| const [mailError, setMailError] = useState(""); // Wrong mail typed | |||
| const [mailErrorMessage, setMailErrorMessage] = useState(""); // Error message caused by typing wrong mail | |||
| const [PIBError, setPIBError] = useState(""); // Wrong PIB typed | |||
| const [PIBErrorMessage, setPIBErrorMessage] = useState(""); // Error message caused by typing wrong PIB | |||
| const [imageError, setImageError] = useState(false); // Not picked image | |||
| const handleResponseSuccess = () => { | |||
| history.push(REGISTER_SUCCESSFUL_PAGE); | |||
| }; | |||
| const handleResponseError = (error) => { | |||
| console.log(error); | |||
| const { mail, password, PIB, image } = informations; | |||
| if (error.type === "mail") { | |||
| const { mail } = informations; | |||
| setInformations({}); | |||
| setInformations({image}); | |||
| setCurrentStep(1); | |||
| setMailError(mail); | |||
| if ( | |||
| @@ -52,8 +58,7 @@ const Register = () => { | |||
| setMailErrorMessage(t("register.emailFormat")); | |||
| } | |||
| } else { | |||
| const { mail, password, PIB } = informations; | |||
| setInformations({ mail, password }); | |||
| setInformations({ mail, password, image }); | |||
| setCurrentStep(2); | |||
| setPIBError(PIB.toString()); | |||
| setPIBErrorMessage(t("register.PIBTaken")); | |||
| @@ -70,67 +75,93 @@ const Register = () => { | |||
| if (currentStep !== 3) { | |||
| setCurrentStep((prevState) => prevState + 1); | |||
| } else { | |||
| registerUser({ ...informations, ...values }); | |||
| if (!informations.image) { | |||
| setImageError(true); | |||
| } else { | |||
| registerUser({ ...informations, ...values }); | |||
| } | |||
| } | |||
| setInformations({ ...informations, ...values }); | |||
| }; | |||
| const setImage = (image) => { | |||
| setImageError(false); | |||
| setInformations(prevInfo => ({ | |||
| ...prevInfo, | |||
| image | |||
| })) | |||
| } | |||
| const goStepBack = (stepNumber) => { | |||
| setCurrentStep(stepNumber); | |||
| const { mail, password, image } = informations; | |||
| if (stepNumber === 1) { | |||
| setInformations({}); | |||
| setInformations({image}); | |||
| } | |||
| if (stepNumber === 2) { | |||
| const { mail, password } = informations; | |||
| setInformations({ mail, password }); | |||
| setInformations({ mail, password, image }); | |||
| } | |||
| }; | |||
| return ( | |||
| <RegisterPageContainer currentstep={currentStep}> | |||
| <Logo /> | |||
| <RegisterTitle component="h1" variant="h5"> | |||
| {t("register.title")} | |||
| </RegisterTitle> | |||
| <RegisterDescription component="h1" variant="h6"> | |||
| {t("register.descriptionMain")} | |||
| </RegisterDescription> | |||
| <ProgressContainer> | |||
| <StepProgress | |||
| functions={[() => goStepBack(1), () => goStepBack(2)]} | |||
| current={currentStep} | |||
| numberOfSteps={3} | |||
| /> | |||
| </ProgressContainer> | |||
| {currentStep === 1 && ( | |||
| <FirstPartOfRegistration | |||
| handleSubmit={handleSubmit} | |||
| error={mailError} | |||
| errorMessage={mailErrorMessage} | |||
| /> | |||
| )} | |||
| {currentStep === 2 && ( | |||
| <SecondPartOfRegistration | |||
| handleSubmit={handleSubmit} | |||
| error={PIBError} | |||
| errorMessage={PIBErrorMessage} | |||
| /> | |||
| )} | |||
| {currentStep === 3 && ( | |||
| <ThirdPartOfRegistration handleSubmit={handleSubmit} /> | |||
| )} | |||
| <LoginTextContainer> | |||
| <LoginAltText>{t("register.loginText")}</LoginAltText> | |||
| <Link to="/login" component={NavLink} underline="hover" align="center"> | |||
| {t("register.login")} | |||
| </Link> | |||
| </LoginTextContainer> | |||
| <RegisterPageContent> | |||
| <Logo /> | |||
| <RegisterTitle component="h1" variant="h5"> | |||
| {t("register.title")} | |||
| </RegisterTitle> | |||
| <RegisterDescription component="h1" variant="h6"> | |||
| {t("register.descriptionMain")} | |||
| </RegisterDescription> | |||
| <ProgressContainer> | |||
| <StepProgress | |||
| functions={[() => goStepBack(1), () => goStepBack(2)]} | |||
| current={currentStep} | |||
| numberOfSteps={3} | |||
| /> | |||
| </ProgressContainer> | |||
| <ProfileImagePicker setImage={setImage} > | |||
| <ProfilePicture /> | |||
| </ProfileImagePicker> | |||
| {currentStep === 1 && ( | |||
| <FirstPartOfRegistration | |||
| handleSubmit={handleSubmit} | |||
| error={mailError} | |||
| errorMessage={mailErrorMessage} | |||
| /> | |||
| )} | |||
| {currentStep === 2 && ( | |||
| <SecondPartOfRegistration | |||
| handleSubmit={handleSubmit} | |||
| error={PIBError} | |||
| errorMessage={PIBErrorMessage} | |||
| /> | |||
| )} | |||
| {currentStep === 3 && ( | |||
| <ThirdPartOfRegistration handleSubmit={handleSubmit} /> | |||
| )} | |||
| {imageError && <ErrorMessage>{t("register.imageError")}</ErrorMessage>} | |||
| <LoginTextContainer> | |||
| <LoginAltText>{t("register.loginText")}</LoginAltText> | |||
| <Link | |||
| to="/login" | |||
| component={NavLink} | |||
| underline="hover" | |||
| align="center" | |||
| > | |||
| {t("register.login")} | |||
| </Link> | |||
| </LoginTextContainer> | |||
| </RegisterPageContent> | |||
| <Footer> | |||
| <FooterText> | |||
| @@ -1,9 +1,11 @@ | |||
| import { Box, Container, Typography } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import ImagePicker from "../../../components/ImagePicker/ImagePicker"; | |||
| import selectedTheme from "../../../themes"; | |||
| import { ReactComponent as ProfilePictureSVG } from "../../../assets/images/profile-picture.svg"; | |||
| export const RegisterPageContainer = styled(Container)` | |||
| margin-top: 100px; | |||
| margin-top: 72px; | |||
| display: flex; | |||
| flex-direction: column; | |||
| align-items: center; | |||
| @@ -11,6 +13,8 @@ export const RegisterPageContainer = styled(Container)` | |||
| padding: 0; | |||
| flex: 1; | |||
| position: relative; | |||
| transition: 1s all; | |||
| ${props => props.currentstep === 3 && `margin-top: 40px`}; | |||
| @media (max-height: 900px) { | |||
| margin-top: 60px; | |||
| } | |||
| @@ -18,8 +22,8 @@ export const RegisterPageContainer = styled(Container)` | |||
| margin-top: 30px; | |||
| flex: none; | |||
| height: 95vh; | |||
| ${props => props.currentstep === 3 && `height: 105vh`}; | |||
| ${props => props.currentstep === 2 && `height: 100vh`}; | |||
| ${(props) => props.currentstep === 3 && `height: 105vh`}; | |||
| ${(props) => props.currentstep === 2 && `height: 100vh`}; | |||
| } | |||
| `; | |||
| export const RegisterTitle = styled(Typography)` | |||
| @@ -34,7 +38,7 @@ export const RegisterTitle = styled(Typography)` | |||
| color: ${selectedTheme.primaryPurple}; | |||
| margin-top: 34px; | |||
| @media (max-height: 800px) { | |||
| margin-top: 26px; | |||
| margin-top: 26px; | |||
| } | |||
| `; | |||
| export const RegisterDescription = styled(Typography)` | |||
| @@ -51,8 +55,8 @@ export const RegisterDescription = styled(Typography)` | |||
| color: ${selectedTheme.primaryGrayText}; | |||
| margin-bottom: 20px; | |||
| @media (max-height: 800px) { | |||
| margin-bottom: 14px; | |||
| margin-top: 6px; | |||
| margin-bottom: 14px; | |||
| margin-top: 6px; | |||
| } | |||
| `; | |||
| export const FormContainer = styled(Box)` | |||
| @@ -64,7 +68,7 @@ export const LoginAltText = styled(Typography)` | |||
| font-size: 14px; | |||
| padding-right: 6px; | |||
| line-height: 14px; | |||
| ` | |||
| `; | |||
| export const LoginTextContainer = styled(Box)` | |||
| display: flex; | |||
| flex-direction: row; | |||
| @@ -73,11 +77,11 @@ export const LoginTextContainer = styled(Box)` | |||
| @media (max-height: 800px) { | |||
| margin-top: 26px; | |||
| } | |||
| ` | |||
| `; | |||
| export const ProgressContainer = styled(Container)` | |||
| width: 100%; | |||
| padding: 0; | |||
| ` | |||
| width: 100%; | |||
| padding: 0; | |||
| `; | |||
| export const Footer = styled(Box)` | |||
| position: absolute; | |||
| bottom: 36px; | |||
| @@ -88,7 +92,7 @@ export const Footer = styled(Box)` | |||
| @media (max-height: 800px) { | |||
| bottom: 10px; | |||
| } | |||
| ` | |||
| `; | |||
| export const FooterText = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| color: #505050; | |||
| @@ -98,4 +102,46 @@ export const FooterText = styled(Typography)` | |||
| font-weight: 400; | |||
| padding: 0; | |||
| font-size: 12px; | |||
| `; | |||
| export const ProfileImagePicker = styled(ImagePicker)` | |||
| background: none; | |||
| margin: 36px; | |||
| background: ${selectedTheme.primaryIconBackgroundColor}; | |||
| background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='100' ry='100' stroke='%235A3984FF' stroke-width='2' stroke-dasharray='7%2c 12' stroke-dashoffset='44' stroke-linecap='square'/%3e%3c/svg%3e"); | |||
| border-radius: 100px; | |||
| overflow: hidden; | |||
| position: relative; | |||
| margin-bottom: 5px; | |||
| `; | |||
| export const ProfilePicture = styled(ProfilePictureSVG)` | |||
| position: absolute; | |||
| left: 36px; | |||
| top: 24px; | |||
| z-index: 0; | |||
| `; | |||
| export const RegisterPageContent = styled(Box)` | |||
| display: flex; | |||
| flex-direction: column; | |||
| align-items: center; | |||
| width: 335px; | |||
| padding: 0; | |||
| flex: 1; | |||
| position: relative; | |||
| 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; | |||
| font-family: "Open Sans"; | |||
| position: relative; | |||
| top: 5px; | |||
| text-align: left; | |||
| font-size: 14px; | |||
| width: 100%; | |||
| ` | |||
| @@ -1,166 +1,167 @@ | |||
| export default { | |||
| accounts: { | |||
| get: 'accounts/{accountUid}', | |||
| forgotPassword: 'forgot-password', | |||
| resetPassword: 'reset-password', | |||
| get: "accounts/{accountUid}", | |||
| forgotPassword: "forgot-password", | |||
| resetPassword: "reset-password", | |||
| getCurrentUserPermissions: | |||
| 'accounts/{currentAccountUid}/users/{currentUserUid}/permissions', | |||
| getAddresses: 'accounts/{accountUid}/addresses', | |||
| updateAddress: 'account/{accountUid}/addresses/{addressUid}', | |||
| deleteAddress: 'accounts/{accountUid}/addresses/{addressUid}', | |||
| getUsers: 'accounts/{accountUid}/users', | |||
| register: 'users', | |||
| updateUser: 'account/{accountUid}/users/{userUid}?actionType={actionType}', | |||
| deleteUser: 'accounts/{accountUid}/users/{userUid}', | |||
| getSettings: 'accounts/{accountUid}/settings', | |||
| getIraSettings: 'accounts/{accountUid}/iraSettings', | |||
| getSettingsRegistration: 'application/settings', | |||
| agreement: 'accounts/agreement', | |||
| "accounts/{currentAccountUid}/users/{currentUserUid}/permissions", | |||
| getAddresses: "accounts/{accountUid}/addresses", | |||
| updateAddress: "account/{accountUid}/addresses/{addressUid}", | |||
| deleteAddress: "accounts/{accountUid}/addresses/{addressUid}", | |||
| getUsers: "accounts/{accountUid}/users", | |||
| register: "users", | |||
| updateUser: "account/{accountUid}/users/{userUid}?actionType={actionType}", | |||
| deleteUser: "accounts/{accountUid}/users/{userUid}", | |||
| getSettings: "accounts/{accountUid}/settings", | |||
| getIraSettings: "accounts/{accountUid}/iraSettings", | |||
| getSettingsRegistration: "application/settings", | |||
| agreement: "accounts/agreement", | |||
| }, | |||
| authentications: { | |||
| getUsernames: 'authenticate/usernames', | |||
| login: 'auth/token', | |||
| logout: 'auth/logout', | |||
| getUserSecurityQuestion: 'users/username/securityquestion', | |||
| confirmSecurityQuestion: 'authenticate/confirm', | |||
| confirmForgotPassword: 'users/passwords/reset_token', | |||
| resetPassword: 'reset-password', | |||
| forgotPassword: 'forgot-password', | |||
| refreshToken: '/auth/refresh', | |||
| generateToken: '/authenticate/generate', | |||
| getUsernames: "authenticate/usernames", | |||
| login: "auth/token", | |||
| logout: "auth/logout", | |||
| getUserSecurityQuestion: "users/username/securityquestion", | |||
| confirmSecurityQuestion: "authenticate/confirm", | |||
| confirmForgotPassword: "users/passwords/reset_token", | |||
| resetPassword: "reset-password", | |||
| forgotPassword: "forgot-password", | |||
| refreshToken: "/auth/refresh", | |||
| generateToken: "/authenticate/generate", | |||
| authenticate: | |||
| '/authenticate?fp={fp}&offer={offer}&landingPageUrl={landingPageUrl}®istrationFlowType={registrationFlowType}', | |||
| "/authenticate?fp={fp}&offer={offer}&landingPageUrl={landingPageUrl}®istrationFlowType={registrationFlowType}", | |||
| confirmAuthentication: | |||
| '/authenticate/confirm?fp={fp}&offer={offer}&landingPageUrl={landingPageUrl}®istrationFlowType={registrationFlowType}', | |||
| "/authenticate/confirm?fp={fp}&offer={offer}&landingPageUrl={landingPageUrl}®istrationFlowType={registrationFlowType}", | |||
| }, | |||
| bankAccounts: { | |||
| get: 'accounts/{accountUid}/bankaccounts', | |||
| get: "accounts/{accountUid}/bankaccounts", | |||
| getBankAccount: | |||
| 'accounts/{accountUid}/bankaccounts/{bankAccountUid}?type={type}', | |||
| "accounts/{accountUid}/bankaccounts/{bankAccountUid}?type={type}", | |||
| getBankAccountsByType: | |||
| 'accounts/{accountUid}/bankaccounts?type={type}&active=true', | |||
| getBankDetailsByRoutingNumber: 'banks/{routingNumber}', | |||
| newAccount: 'accounts/{accountUid}/bankaccounts', | |||
| "accounts/{accountUid}/bankaccounts?type={type}&active=true", | |||
| getBankDetailsByRoutingNumber: "banks/{routingNumber}", | |||
| newAccount: "accounts/{accountUid}/bankaccounts", | |||
| deleteAccount: | |||
| 'accounts/{accountUid}/bankaccounts/{bankAccountUid}?type={type}', | |||
| verify: '/accounts/{accountUid}/bankaccountverification/{bankAccountUid}', | |||
| postBankAccountRegistration: '/accounts/{applicationUid}/bankaccounts', | |||
| getRegistration: 'banks/{applicationUid}/bankaccounts', | |||
| "accounts/{accountUid}/bankaccounts/{bankAccountUid}?type={type}", | |||
| verify: "/accounts/{accountUid}/bankaccountverification/{bankAccountUid}", | |||
| postBankAccountRegistration: "/accounts/{applicationUid}/bankaccounts", | |||
| getRegistration: "banks/{applicationUid}/bankaccounts", | |||
| }, | |||
| documents: { | |||
| getDocuments: 'accounts/{accountUid}/documents?year={year}', | |||
| getDocument: 'accounts/{accountUid}/documents/{documentType}', | |||
| getDocuments: "accounts/{accountUid}/documents?year={year}", | |||
| getDocument: "accounts/{accountUid}/documents/{documentType}", | |||
| }, | |||
| countries: '/countries', | |||
| countries: "/countries", | |||
| metalStream: { | |||
| getMetalStreamSettings: 'accounts/{accountUid}/metalstream', | |||
| getMetalStreamFundings: 'applications/{applicationUid}/metalStreamFunding', | |||
| getMetalStreamSettings: "accounts/{accountUid}/metalstream", | |||
| getMetalStreamFundings: "applications/{applicationUid}/metalStreamFunding", | |||
| }, | |||
| orders: { | |||
| buyForStorage: '/accounts/{accountUid}/orders/buyForStorage', | |||
| buyForDelivery: '/accounts/{accountUid}/orders/buyForDelivery', | |||
| verifyBuyForDelivery: '/accounts/{accountUid}/orders/buyForDelivery/verify', | |||
| sellFromStorage: '/accounts/{accountUid}/orders/sellFromStorage', | |||
| fractionalConversion: '/accounts/{accountUid}/orders/fractionalConversion', | |||
| buyForStorage: "/accounts/{accountUid}/orders/buyForStorage", | |||
| buyForDelivery: "/accounts/{accountUid}/orders/buyForDelivery", | |||
| verifyBuyForDelivery: "/accounts/{accountUid}/orders/buyForDelivery/verify", | |||
| sellFromStorage: "/accounts/{accountUid}/orders/sellFromStorage", | |||
| fractionalConversion: "/accounts/{accountUid}/orders/fractionalConversion", | |||
| deliverFromStorageVerify: | |||
| '/accounts/{accountUid}/orders/deliverFromStorage/verify', | |||
| deliverFromStorage: '/accounts/{accountUid}/orders/deliverFromStorage', | |||
| iraCashDistribution: '/accounts/{accountUid}/orders/iraCashDistribution', | |||
| iraCashTransfer: '/accounts/{accountUid}/orders/iraCashTransfer', | |||
| iraFeeWithdrawal: 'accounts/{accountUid}/orders/iraFeeWithdrawal', | |||
| achDeposit: 'accounts/{accountUid}/orders/achDeposit', | |||
| wireWithdrawal: '/accounts/{accountUid}/orders/wireWithdrawal', | |||
| checkWithdrawal: '/accounts/{accountUid}/orders/checkWithdrawal', | |||
| "/accounts/{accountUid}/orders/deliverFromStorage/verify", | |||
| deliverFromStorage: "/accounts/{accountUid}/orders/deliverFromStorage", | |||
| iraCashDistribution: "/accounts/{accountUid}/orders/iraCashDistribution", | |||
| iraCashTransfer: "/accounts/{accountUid}/orders/iraCashTransfer", | |||
| iraFeeWithdrawal: "accounts/{accountUid}/orders/iraFeeWithdrawal", | |||
| achDeposit: "accounts/{accountUid}/orders/achDeposit", | |||
| wireWithdrawal: "/accounts/{accountUid}/orders/wireWithdrawal", | |||
| checkWithdrawal: "/accounts/{accountUid}/orders/checkWithdrawal", | |||
| }, | |||
| portfolio: { | |||
| getPortfolioValuations: 'accounts/{accountUid}/portfolio/valuations', | |||
| getPortfolioMetalPrices: 'marketprices', | |||
| getPortfolioValuations: "accounts/{accountUid}/portfolio/valuations", | |||
| getPortfolioMetalPrices: "marketprices", | |||
| getPortfolioHoldings: | |||
| 'accounts/{accountUid}/portfolio/products?valuation=true', | |||
| getPortfolioProductCodes: '/accounts/{accountUid}/portfolio/productcodes', | |||
| getPortfolioBalances: '/accounts/{accountUid}/portfolio/balances', | |||
| "accounts/{accountUid}/portfolio/products?valuation=true", | |||
| getPortfolioProductCodes: "/accounts/{accountUid}/portfolio/productcodes", | |||
| getPortfolioBalances: "/accounts/{accountUid}/portfolio/balances", | |||
| getPortfolioProductBySymbol: | |||
| '/accounts/{accountUid}/portfolio/products/{symbol}', | |||
| getPortfolioTransactions: '/accounts/{accountUid}/transactions', | |||
| "/accounts/{accountUid}/portfolio/products/{symbol}", | |||
| getPortfolioTransactions: "/accounts/{accountUid}/transactions", | |||
| getPortfolioSingleTransaction: | |||
| '/accounts/{accountUid}/transactions/{transactionUid}', | |||
| getProductPortoflioTransactions: 'accounts/{accountUid}/transactions', | |||
| "/accounts/{accountUid}/transactions/{transactionUid}", | |||
| getProductPortoflioTransactions: "accounts/{accountUid}/transactions", | |||
| getRecentPortfolioTransactions: | |||
| 'accounts/{accountUid}/transactions?content=Recent', | |||
| getFinancialPortfolioTransactions: 'accounts/{accountUid}/transactions', | |||
| "accounts/{accountUid}/transactions?content=Recent", | |||
| getFinancialPortfolioTransactions: "accounts/{accountUid}/transactions", | |||
| getFinancialPortfolioPendingTransactions: | |||
| 'accounts/{accountUid}/transactions/fundinghistory', | |||
| "accounts/{accountUid}/transactions/fundinghistory", | |||
| patchFinancialPortfolioPendingTransactions: | |||
| '/accounts/{accountUid}/transactions/fundinghistory/{depositKey}', | |||
| "/accounts/{accountUid}/transactions/fundinghistory/{depositKey}", | |||
| }, | |||
| products: { | |||
| getPrices: '/accounts/{accountUid}/products/prices', | |||
| prices: 'accounts/{accountUid}/products/prices?side={side}', | |||
| getPrices: "/accounts/{accountUid}/products/prices", | |||
| prices: "accounts/{accountUid}/products/prices?side={side}", | |||
| tiers: | |||
| '/accounts/{accountUid}/products/prices/{symbol}/tiers?side={side}&location={location}', | |||
| symbolPrices: '/accounts/{accountUid}/products/{symbol}/prices?side={side}', | |||
| getPricesRegistration: 'applications/{applicationUid}/products/prices', | |||
| "/accounts/{accountUid}/products/prices/{symbol}/tiers?side={side}&location={location}", | |||
| symbolPrices: "/accounts/{accountUid}/products/{symbol}/prices?side={side}", | |||
| getPricesRegistration: "applications/{applicationUid}/products/prices", | |||
| }, | |||
| settings: { | |||
| get: 'settings', | |||
| get: "settings", | |||
| }, | |||
| taxForms: { | |||
| getTaxForms: 'settings/taxForms/{applicationType}', | |||
| getTaxForms: "settings/taxForms/{applicationType}", | |||
| }, | |||
| users: { | |||
| getAccounts: '/users/{userUid}/accounts', | |||
| getRegistrationAccounts: '/users/{userUid}/accounts', | |||
| updateUser: '/users/{userUid}?updateUserActionType={actionType}', | |||
| updateUserPassword: '/users/{userUid}/passwords', | |||
| logout: '/auth/logout', | |||
| getUsernames: '/users/email', | |||
| getAccounts: "/users/{userUid}/accounts", | |||
| getRegistrationAccounts: "/users/{userUid}/accounts", | |||
| updateUser: "/users/{userUid}?updateUserActionType={actionType}", | |||
| updateUserPassword: "/users/{userUid}/passwords", | |||
| logout: "/auth/logout", | |||
| getUsernames: "/users/email", | |||
| createUser: | |||
| '/users?fp={fp}&offer={offer}&landingPageUrl={landingPageUrl}®istrationFlowType={registrationFlowType}', | |||
| updateUserRegistration: '/users/{userUid}', | |||
| invite: '/users/invite', | |||
| "/users?fp={fp}&offer={offer}&landingPageUrl={landingPageUrl}®istrationFlowType={registrationFlowType}", | |||
| updateUserRegistration: "/users/{userUid}", | |||
| invite: "/users/invite", | |||
| }, | |||
| applications: { | |||
| application: '/applications/{applicationUid}', | |||
| addPerson: '/applications/{applicationUid}/persons', | |||
| updatePerson: '/applications/{applicationUid}/persons/{personUid}', | |||
| application: "/applications/{applicationUid}", | |||
| addPerson: "/applications/{applicationUid}/persons", | |||
| updatePerson: "/applications/{applicationUid}/persons/{personUid}", | |||
| addPersonWithGiftState: | |||
| '/applications/{applicationUid}/UTMA/persons?giftState={giftState}', | |||
| "/applications/{applicationUid}/UTMA/persons?giftState={giftState}", | |||
| updatePersonWithGiftState: | |||
| '/applications/{applicationUid}/UTMA/persons/{personUid}?giftState={giftState}', | |||
| "/applications/{applicationUid}/UTMA/persons/{personUid}?giftState={giftState}", | |||
| addPersonWithCompanyName: | |||
| '/applications/{applicationUid}/IRA/persons?companyName={companyName}', | |||
| "/applications/{applicationUid}/IRA/persons?companyName={companyName}", | |||
| updatePersonWithCompanyName: | |||
| '/applications/{applicationUid}/IRA/persons/{personUid}?companyName={companyName}', | |||
| submitLegalEntity: '/applications/{applicationUid}/legalEntities', | |||
| "/applications/{applicationUid}/IRA/persons/{personUid}?companyName={companyName}", | |||
| submitLegalEntity: "/applications/{applicationUid}/legalEntities", | |||
| updateLegalEntity: | |||
| '/applications/{applicationUid}/legalEntities/{personUid}', | |||
| postNonIraFunding: '/applications/{applicationUid}/funding', | |||
| postIraFunding: '/applications/{applicationUid}/iraFunding', | |||
| postMSFunding: '/applications/{applicationUid}/metalStreamFunding', | |||
| consent: '/applications/{applicationUid}/consents', | |||
| "/applications/{applicationUid}/legalEntities/{personUid}", | |||
| postNonIraFunding: "/applications/{applicationUid}/funding", | |||
| postIraFunding: "/applications/{applicationUid}/iraFunding", | |||
| postMSFunding: "/applications/{applicationUid}/metalStreamFunding", | |||
| consent: "/applications/{applicationUid}/consents", | |||
| updateConsent: `/applications/{applicationUid}/consents/{agreementConsentUid}`, | |||
| submitMetalStreamRegistration: | |||
| '/applications/{applicationUid}/metalStreamFunding', | |||
| "/applications/{applicationUid}/metalStreamFunding", | |||
| }, | |||
| common: { | |||
| getCountries: '/countries/', | |||
| getTaxForms: '/taxForms/', | |||
| getContributionYears: 'contributionYears', | |||
| getCountryStates: '/countries/{iso3CountryCode}/states/', | |||
| getSecurityQuestions: '/registration/securityQuestions/', | |||
| getPortalSecurityQuestions: '/securityQuestions', | |||
| getCountries: "/countries/", | |||
| getTaxForms: "/taxForms/", | |||
| getContributionYears: "contributionYears", | |||
| getCountryStates: "/countries/{iso3CountryCode}/states/", | |||
| getSecurityQuestions: "/registration/securityQuestions/", | |||
| getPortalSecurityQuestions: "/securityQuestions", | |||
| }, | |||
| plaid: { | |||
| getToken: '/bankaccounts/createplaidlinktoken', | |||
| getToken: "/bankaccounts/createplaidlinktoken", | |||
| }, | |||
| affiliate: { | |||
| setCookie: '/affiliate/picture', | |||
| setFingerprint: '/affiliate/fingerprint', | |||
| setCookie: "/affiliate/picture", | |||
| setFingerprint: "/affiliate/fingerprint", | |||
| }, | |||
| offers: { | |||
| getOffers: 'offers', | |||
| addOffer: 'offers', | |||
| categories: 'categories', | |||
| locations: 'locations' | |||
| } | |||
| getOffers: "/offers", | |||
| getOneOffer: "/offers", | |||
| addOffer: "/offers", | |||
| categories: "categories", | |||
| locations: "locations", | |||
| }, | |||
| }; | |||
| @@ -5,6 +5,11 @@ export const attemptFetchOffers = (payload) => { | |||
| if (payload) return getRequest(apiEndpoints.offers.getOffers + payload + "&size=10") | |||
| return getRequest(apiEndpoints.offers.getOffers + "?size=10") | |||
| } | |||
| export const attemptFetchOneOffer = (payload) => { | |||
| // console.log(payload); | |||
| const url = `${apiEndpoints.offers.getOneOffer}/${payload.payload}`; | |||
| return getRequest(url); | |||
| } | |||
| export const attemptAddOffer = (payload) => { | |||
| return postRequest(apiEndpoints.offers.addOffer, payload) | |||
| } | |||
| @@ -1,12 +1,18 @@ | |||
| import { createClearType, createErrorType, createFetchType, createSuccessType } from "../actionHelpers"; | |||
| const OFFERS_SCOPE = "OFFERS_SCOPE"; | |||
| const ONE_OFFER_SCOPE = "ONE_OFFER_SCOPE" | |||
| export const OFFERS_FETCH = createFetchType(OFFERS_SCOPE); | |||
| export const OFFERS_SUCCESS = createSuccessType(OFFERS_SCOPE); | |||
| export const OFFERS_ERROR = createErrorType(OFFERS_SCOPE); | |||
| export const OFFERS_CLEAR = createClearType(OFFERS_SCOPE); | |||
| export const ONE_OFFER_FETCH = createFetchType(ONE_OFFER_SCOPE); | |||
| export const ONE_OFFER_SUCCESS = createSuccessType(ONE_OFFER_FETCH); | |||
| export const ONE_OFFER_ERROR = createErrorType(ONE_OFFER_SCOPE); | |||
| export const OFFERS_SET = "OFFERS_SET"; | |||
| export const OFFER_SET = "OFFER_SET" | |||
| export const OFFERS_ADD = "OFFERS_ADD"; | |||
| export const OFFER_ADD = "OFFER_ADD"; | |||
| @@ -1,4 +1,4 @@ | |||
| import { OFFERS_ADD, OFFERS_CLEAR, OFFERS_ERROR, OFFERS_FETCH, OFFERS_SET, OFFERS_SUCCESS, OFFER_ADD } from "./offersActionConstants"; | |||
| import { OFFERS_ADD, OFFERS_CLEAR, OFFERS_ERROR, OFFERS_FETCH, OFFERS_SET, OFFERS_SUCCESS, OFFER_ADD, ONE_OFFER_FETCH, ONE_OFFER_SUCCESS, ONE_OFFER_ERROR, OFFER_SET } from "./offersActionConstants"; | |||
| export const fetchOffers = (payload) => ({ | |||
| type: OFFERS_FETCH, | |||
| @@ -26,4 +26,24 @@ export const addOffers = (payload) => ({ | |||
| export const addOffer = (payload) => ({ | |||
| type: OFFER_ADD, | |||
| payload | |||
| }) | |||
| // | |||
| export const fetchOneOffer = (payload) => ({ | |||
| type: ONE_OFFER_FETCH, | |||
| payload | |||
| }) | |||
| export const fetchOneOfferError = (payload) => ({ | |||
| type: ONE_OFFER_ERROR, | |||
| payload | |||
| }) | |||
| export const fetchOneOfferSuccess = (payload) => ({ | |||
| type: ONE_OFFER_SUCCESS, | |||
| payload | |||
| }) | |||
| export const setOffer = (payload) => ({ | |||
| type: OFFER_SET, | |||
| payload | |||
| }) | |||
| @@ -4,6 +4,10 @@ import { | |||
| OFFERS_ERROR, | |||
| OFFERS_SET, | |||
| OFFER_ADD, | |||
| OFFER_SET, | |||
| ONE_OFFER_FETCH, | |||
| ONE_OFFER_ERROR, | |||
| ONE_OFFER_SUCCESS, | |||
| } from "../../actions/offers/offersActionConstants"; | |||
| import createReducer from "../../utils/createReducer"; | |||
| @@ -11,6 +15,7 @@ const initialState = { | |||
| offers: [], | |||
| error: "", | |||
| newOffer: "", | |||
| selectedOffer:"", | |||
| }; | |||
| export default createReducer( | |||
| @@ -20,6 +25,11 @@ export default createReducer( | |||
| [OFFERS_SET]: setOffers, | |||
| [OFFERS_ADD]: addOffers, | |||
| [OFFER_ADD]: addOffer, | |||
| [OFFER_SET]: setOffer, | |||
| [ONE_OFFER_ERROR]: fetchOneOfferError, | |||
| [ONE_OFFER_SUCCESS]: fetchOneOfferSuccess, | |||
| [ONE_OFFER_FETCH]: fetchOneOffer, | |||
| }, | |||
| initialState | |||
| ); | |||
| @@ -37,6 +47,12 @@ function setOffers(state, action) { | |||
| offers: action.payload, | |||
| }; | |||
| } | |||
| function setOffer(state, action) { | |||
| return { | |||
| ...state, | |||
| selectedOffer: action.payload, | |||
| }; | |||
| } | |||
| function addOffers(state, action) { | |||
| return { | |||
| ...state, | |||
| @@ -49,3 +65,22 @@ function addOffer(state, action) { | |||
| offer: action.payload | |||
| } | |||
| } | |||
| function fetchOneOffer(state,action) { | |||
| return { | |||
| ...state, | |||
| selectedOffer: action.payload | |||
| } | |||
| } | |||
| function fetchOneOfferSuccess( state, action) { | |||
| return { | |||
| ...state, | |||
| selectedOffer: action.payload | |||
| } | |||
| } | |||
| function fetchOneOfferError (state, action) { | |||
| return { | |||
| ...state, | |||
| error: action.payload | |||
| } | |||
| } | |||
| @@ -4,8 +4,8 @@ import { FORGOT_PASSWORD, RESET_PASSWORD } from "../actions/user/userActionConst | |||
| function* forgotPassword({payload}) { | |||
| try { | |||
| console.log(payload) | |||
| const data = yield call(forgotPasswordRequest, payload.email); | |||
| console.log(data); | |||
| if (data) { | |||
| if (payload.handleResponseSuccess) { | |||
| yield call(payload.handleResponseSuccess); | |||
| @@ -13,6 +13,7 @@ function* forgotPassword({payload}) { | |||
| } | |||
| } | |||
| catch(e) { | |||
| console.log(e); | |||
| if (payload.handleResponseError) { | |||
| yield call(payload.handleResponseError); | |||
| } | |||
| @@ -63,8 +63,9 @@ function* fetchUser({ payload }) { | |||
| if (payload.handleApiResponseError) { | |||
| yield call(payload.handleApiResponseError, e.response.status); | |||
| } | |||
| let errorMessage = yield call(rejectErrorCodeHelper, e); | |||
| if (e.response.status === 401) { | |||
| console.log(e.response.status); | |||
| let errorMessage = yield call(rejectErrorCodeHelper, e.response.status); | |||
| if (e.response.status === 400) { | |||
| errorMessage = i18next.t("login.wrongCredentials", { | |||
| lng: "rs" | |||
| }); | |||
| @@ -2,12 +2,14 @@ import { all, takeLatest, call, put } from "@redux-saga/core/effects"; | |||
| import { | |||
| attemptAddOffer, | |||
| attemptFetchOffers, | |||
| attemptFetchOneOffer, | |||
| } from "../../request/offersRequest"; | |||
| import { | |||
| OFFERS_FETCH, | |||
| OFFER_ADD, | |||
| ONE_OFFER_FETCH, | |||
| } from "../actions/offers/offersActionConstants"; | |||
| import { setOffers } from "../actions/offers/offersActions"; | |||
| import { setOffers, setOffer } from "../actions/offers/offersActions"; | |||
| function* fetchOffers(payload) { | |||
| try { | |||
| @@ -38,9 +40,21 @@ function* createOffer(payload) { | |||
| } | |||
| } | |||
| function* fetchOneOffer(payload) { | |||
| try { | |||
| console.log(payload); | |||
| const data = yield call(attemptFetchOneOffer, payload); | |||
| //console.log(data.data); | |||
| yield put(setOffer(data.data)); | |||
| } catch (e) { | |||
| console.log(e); | |||
| } | |||
| } | |||
| export default function* offersSaga() { | |||
| yield all([ | |||
| takeLatest(OFFERS_FETCH, fetchOffers), | |||
| takeLatest(OFFER_ADD, createOffer), | |||
| takeLatest(ONE_OFFER_FETCH, fetchOneOffer), | |||
| ]); | |||
| } | |||
| @@ -4,13 +4,13 @@ import { REGISTER_USER_FETCH } from "../actions/register/registerActionConstants | |||
| function* fetchRegisterUser({ payload }) { | |||
| try { | |||
| const requestData = { | |||
| email: payload.values.mail.toString(), | |||
| password: payload.values.password.toString(), | |||
| roles: [ | |||
| "User", | |||
| ], | |||
| image: payload.values.image.replace("data:image/png;base64,", ""), | |||
| company: { | |||
| name: payload.values.nameOfFirm.toString(), | |||
| PIB: payload.values.PIB.toString(), | |||
| @@ -7,6 +7,11 @@ export const selectOffers = createSelector( | |||
| (state) => state.offers, | |||
| ); | |||
| export const selectOffer = createSelector( | |||
| offersSelector, | |||
| (state) => state.selectedOffer, | |||
| ); | |||
| export const selectOffersError = createSelector( | |||
| offersSelector, | |||
| (state) => state.error, | |||
| @@ -15,5 +15,5 @@ export const primaryThemeColors = { | |||
| selectOptionTextColor: "#1D1D1D", | |||
| primaryDarkText: "#505050", | |||
| iconStrokeColor: "#8C8C8C", | |||
| // iconStrokeDisabledColor: "#818181", | |||
| iconStrokeDisabledColor: "#818181", | |||
| }; | |||
| @@ -1,14 +1,9 @@ | |||
| import i18next from 'i18next'; | |||
| import i18next from "i18next"; | |||
| export const rejectErrorCodeHelper = (error) => { | |||
| if (error?.response?.data?.Errors) { | |||
| const errorCode = error?.response?.data?.Errors[0]?.Code; | |||
| const errorMessage = errorCode | |||
| ? i18next.t(`apiErrors.${errorCode}`) | |||
| : i18next.t('apiErrors.SomethingWentWrong'); | |||
| export const rejectErrorCodeHelper = (errorCode) => { | |||
| const errorMessage = errorCode | |||
| ? i18next.t(`apiErrors.${errorCode}`) | |||
| : i18next.t("apiErrors.SomethingWentWrong"); | |||
| return errorMessage; | |||
| } | |||
| return i18next.t('apiErrors.SomethingWentWrong'); | |||
| return errorMessage; | |||
| }; | |||