| @@ -0,0 +1,4 @@ | |||
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M19 12L5 12" stroke="#1D1D1D" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/> | |||
| <path d="M12 19L5 12L12 5" stroke="#1D1D1D" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/> | |||
| </svg> | |||
| @@ -0,0 +1,4 @@ | |||
| <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> | |||
| <path d="M18 6L6 18" stroke="#1D1D1D" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> | |||
| <path d="M6 6L18 18" stroke="#1D1D1D" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> | |||
| </svg> | |||
| @@ -1,41 +1,45 @@ | |||
| import IconButton from "../../IconButton/IconButton" | |||
| import {ReactComponent as DownArrow} from "../../../assets/images/svg/arrow-down.svg" | |||
| import IconButton from "../../IconButton/IconButton"; | |||
| import { ReactComponent as DownArrow } from "../../../assets/images/svg/arrow-down.svg"; | |||
| import styled from "styled-components"; | |||
| import selectedTheme from "../../../themes"; | |||
| export const ArrowIcon = styled(DownArrow)` | |||
| ${props => props.side === 'left' && ` | |||
| ${(props) => | |||
| props.side === "left" && | |||
| ` | |||
| transform: rotate(180deg); | |||
| `} | |||
| width: 18px; | |||
| height: 18px; | |||
| & path { | |||
| ${props => props.disabled && ` | |||
| width: 18px; | |||
| height: 18px; | |||
| & path { | |||
| ${(props) => | |||
| props.disabled && | |||
| ` | |||
| stroke: ${selectedTheme.iconStrokeDisabledColor} | |||
| `} | |||
| } | |||
| ` | |||
| } | |||
| `; | |||
| export const ArrowContainer = styled(IconButton)` | |||
| border: 1px solid ${selectedTheme.primaryPurple}; | |||
| border-radius: 100%; | |||
| min-width: 40px; | |||
| width: 40px; | |||
| height: 40px; | |||
| display: flex; | |||
| box-sizing: border-box; | |||
| cursor: pointer; | |||
| margin-top: auto; | |||
| margin-bottom: auto; | |||
| transition: 0.2s all ease; | |||
| &:hover { | |||
| border: 1px solid ${selectedTheme.primaryPurple}; | |||
| border-radius: 100%; | |||
| min-width: 40px; | |||
| width: 40px; | |||
| height: 40px; | |||
| display: flex; | |||
| box-sizing: border-box; | |||
| cursor: pointer; | |||
| margin-top: auto; | |||
| margin-bottom: auto; | |||
| transition: 0.2s all ease; | |||
| &:hover { | |||
| background-color: ${selectedTheme.primaryPurple}; | |||
| & svg path { | |||
| stroke: white; | |||
| stroke: white; | |||
| } | |||
| } | |||
| ${props => props.disabled && ` | |||
| } | |||
| ${(props) => | |||
| props.disabled && | |||
| ` | |||
| border 1px solid ${selectedTheme.iconStrokeDisabledColor}; | |||
| &:hover { | |||
| background-color: inherit; | |||
| @@ -50,4 +54,10 @@ ${props => props.disabled && ` | |||
| } | |||
| `} | |||
| ` | |||
| @media screen and (max-width: 600px) { | |||
| min-width: 32px; | |||
| width: 32px; | |||
| height: 32px; | |||
| } | |||
| `; | |||
| @@ -24,14 +24,24 @@ import { | |||
| RegisterAltText, | |||
| RegisterTextContainer, | |||
| FieldLabel, | |||
| ModalCreateOfferContainer, | |||
| ModalBackDrop, | |||
| ModalHeader, | |||
| BackIcon, | |||
| CloseIcon, | |||
| } from "./CreateOffer.styled"; | |||
| import selectedTheme from "../../../themes"; | |||
| import StepProgress from "../../StepProgress/StepProgress"; | |||
| import { Label } from "../../CheckBox/Label"; | |||
| import FirstPartCreateOffer from "./FirstPart/FirstPartCreateOffer"; | |||
| import SecondPartCreateOffer from "./SecondPart/SecondPartCreateOffer"; | |||
| import ThirdPartCreateOffer from "./ThirdPart/ThirdPartCreateOffer"; | |||
| import { addOffer } from "../../../store/actions/offers/offersActions"; | |||
| import { ReactComponent as ArrowBack } from "../../../assets/images/svg/arrow-back.svg"; | |||
| import { ReactComponent as CloseButton } from "../../../assets/images/svg/close-modal.svg"; | |||
| import BackdropComponent from "../../MUI/BackdropComponent"; | |||
| const CreateOffer = ({ history }) => { | |||
| const CreateOffer = ({ history, closeCreateOfferModal }) => { | |||
| const dispatch = useDispatch(); | |||
| const { t } = useTranslation(); | |||
| const [informations, setInformations] = useState({}); | |||
| @@ -39,6 +49,8 @@ const CreateOffer = ({ history }) => { | |||
| const [currentStep, setCurrentStep] = useState(1); | |||
| const handleClickShowPassword = () => setShowPassword(!showPassword); | |||
| const handleMouseDownPassword = () => setShowPassword(!showPassword); | |||
| const categories = useSelector((state) => state.categories.categories); | |||
| // When user refreshes page | |||
| // useEffect(() => { | |||
| @@ -76,21 +88,127 @@ const CreateOffer = ({ history }) => { | |||
| }; | |||
| const handleNext = (values) => { | |||
| setInformations({...values}); | |||
| setCurrentStep(prevState => prevState+1) | |||
| setInformations({ ...informations, ...values }); | |||
| setCurrentStep((prevState) => prevState + 1); | |||
| }; | |||
| const newImgs = | |||
| informations.images && | |||
| informations.images | |||
| .filter((img) => img !== undefined) | |||
| .map((img) => | |||
| img | |||
| .replace("data:image/jpg;base64,", "") | |||
| .replace("data:image/jpeg;base64,", "") | |||
| .replace("data:image/png;base64,", "") | |||
| ); | |||
| let subcategories = []; | |||
| for (const element of categories) { | |||
| if (element.name === informations.category) { | |||
| subcategories = element.subcategories.map((item) => item.name); | |||
| } | |||
| } | |||
| const offerData = { | |||
| name: informations.nameOfProduct, | |||
| description: informations.description, | |||
| location: { | |||
| city: informations.location, | |||
| }, | |||
| condition: informations.condition, | |||
| category: { | |||
| name: informations.category, | |||
| subcategories: subcategories, | |||
| }, | |||
| subcategory: informations.subcategory, | |||
| images: newImgs, | |||
| }; | |||
| const submitOffer = (values) => { | |||
| dispatch(addOffer(values)); | |||
| }; | |||
| const handleSubmitOffer = () => { | |||
| submitOffer(offerData); | |||
| closeCreateOfferModal(false); | |||
| }; | |||
| const backButtonHandler = () => { | |||
| setCurrentStep((prevState) => prevState - 1); | |||
| }; | |||
| const closeModalHandler = () => { | |||
| closeCreateOfferModal(false); | |||
| }; | |||
| const goStepBack = (stepNumber) => { | |||
| setCurrentStep(stepNumber); | |||
| const { | |||
| category, | |||
| condition, | |||
| description, | |||
| images, | |||
| location, | |||
| nameOfProduct, | |||
| subcategory, | |||
| } = informations; | |||
| if (stepNumber === 1) { | |||
| setInformations({}); | |||
| } | |||
| if (stepNumber === 2) { | |||
| setInformations({ | |||
| category, | |||
| condition, | |||
| description, | |||
| location, | |||
| nameOfProduct, | |||
| subcategory, | |||
| }); | |||
| } | |||
| }; | |||
| return ( | |||
| <CreateOfferContainer> | |||
| <CreateOfferTitle component="h1" variant="h5"> | |||
| Nova Objava | |||
| </CreateOfferTitle> | |||
| <StepProgress current={currentStep} numberOfSteps={3} /> | |||
| {currentStep === 1 && <FirstPartCreateOffer handleNext={handleNext}/>} | |||
| {currentStep === 2 && <SecondPartCreateOffer handleNext={handleNext} />} | |||
| </CreateOfferContainer> | |||
| <> | |||
| <BackdropComponent | |||
| isLoading | |||
| handleClose={closeModalHandler} | |||
| position="fixed" | |||
| /> | |||
| <ModalCreateOfferContainer currentStep={currentStep}> | |||
| <CreateOfferContainer currentStep={currentStep}> | |||
| <ModalHeader> | |||
| <BackIcon onClick={backButtonHandler}> | |||
| {currentStep !== 1 ? <ArrowBack /> : ""} | |||
| </BackIcon> | |||
| <CreateOfferTitle component="h1" variant="h5"> | |||
| {currentStep === 3 ? "Pregled" : "Nova Objava"} | |||
| </CreateOfferTitle> | |||
| <CloseIcon onClick={closeModalHandler}> | |||
| <CloseButton /> | |||
| </CloseIcon> | |||
| </ModalHeader> | |||
| <StepProgress | |||
| current={currentStep} | |||
| numberOfSteps={3} | |||
| functions={[() => goStepBack(1), () => goStepBack(2)]} | |||
| /> | |||
| {currentStep === 1 && ( | |||
| <FirstPartCreateOffer handleNext={handleNext} /> | |||
| )} | |||
| {currentStep === 2 && ( | |||
| <SecondPartCreateOffer handleNext={handleNext} /> | |||
| )} | |||
| {currentStep === 3 && ( | |||
| <ThirdPartCreateOffer | |||
| handleSubmitOffer={handleSubmitOffer} | |||
| informations={informations} | |||
| /> | |||
| )} | |||
| </CreateOfferContainer> | |||
| </ModalCreateOfferContainer> | |||
| </> | |||
| ); | |||
| }; | |||
| @@ -4,17 +4,87 @@ import selectedTheme from "../../../themes"; | |||
| import { Label } from "../../CheckBox/Label"; | |||
| import Select from "../../Select/Select"; | |||
| export const ModalCreateOfferContainer = styled(Box)` | |||
| background-color: #fff; | |||
| position: fixed; | |||
| overflow-y: auto; | |||
| max-height: 90vh; | |||
| top: ${(props) => | |||
| props.currentStep === 1 ? "calc(50% - 345px);" : "calc(50% - 350px);"}; | |||
| left: ${(props) => | |||
| props.currentStep !== 3 ? "calc(50% - 310px);" : "calc(50% - 340px);"}; | |||
| z-index: 150; | |||
| padding: ${(props) => (props.currentStep !== 3 ? "0 120px" : "0 130px")}; | |||
| &::-webkit-scrollbar { | |||
| width: 5px; | |||
| } | |||
| &::-webkit-scrollbar-track { | |||
| background: #ddd; | |||
| } | |||
| &::-webkit-scrollbar-thumb { | |||
| background: #777; | |||
| } | |||
| scrollbar-width: thin; | |||
| scrollbar-color: #ddd; | |||
| @media screen and (max-width: 628px) { | |||
| height: 740px; | |||
| width: 95%; | |||
| left: 10px; | |||
| padding: 0 30px; | |||
| top: 70px; | |||
| } | |||
| `; | |||
| export const ModalHeader = styled(Box)` | |||
| display: flex; | |||
| justify-content: space-between; | |||
| align-items: center; | |||
| `; | |||
| export const BackIcon = styled(Box)` | |||
| cursor: pointer; | |||
| position: absolute; | |||
| left: 40px; | |||
| @media screen and (max-width: 600px) { | |||
| left: 20px; | |||
| & svg { | |||
| width: 20px; | |||
| } | |||
| } | |||
| `; | |||
| export const CloseIcon = styled(Box)` | |||
| cursor: pointer; | |||
| position: absolute; | |||
| right: 40px; | |||
| @media screen and (max-width: 600px) { | |||
| right: 20px; | |||
| & svg { | |||
| width: 20px; | |||
| } | |||
| } | |||
| `; | |||
| export const CreateOfferContainer = styled(Container)` | |||
| margin-top: 0px; | |||
| display: flex; | |||
| width: 380px; | |||
| width: ${props => props.currentStep === 3 ? "580px" : "380px"}; | |||
| flex-direction: column; | |||
| align-items: center; | |||
| @media screen and (max-width: 600px) { | |||
| width: 95%; | |||
| } | |||
| `; | |||
| export const CreateOfferTitle = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| width: 328px; | |||
| height: 33px; | |||
| /* width: 328px; | |||
| height: 33px; */ | |||
| text-align: center; | |||
| flex: 1; | |||
| font-style: normal; | |||
| @@ -24,6 +94,11 @@ export const CreateOfferTitle = styled(Typography)` | |||
| color: ${selectedTheme.primaryPurple}; | |||
| margin-top: 36px; | |||
| margin-bottom: 40px; | |||
| @media screen and (max-width: 600px) { | |||
| font-size: 18px; | |||
| margin-bottom: 30px; | |||
| } | |||
| `; | |||
| export const CreateOfferDescription = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| @@ -1,4 +1,4 @@ | |||
| import React from "react"; | |||
| import React, { useState } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { useFormik } from "formik"; | |||
| import { | |||
| @@ -13,8 +13,16 @@ import selectedTheme from "../../../../themes"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import Option from "../../../Select/Option/Option"; | |||
| import { SelectField } from "../CreateOffer.styled"; | |||
| import { useSelector } from "react-redux"; | |||
| import useScreenDimensions from "../../../../hooks/useScreenDimensions"; | |||
| const FirstPartCreateOffer = (props) => { | |||
| const [subcat, setSubcat] = useState([{}]); | |||
| const locations = useSelector((state) => state.locations.locations); | |||
| const categories = useSelector((state) => state.categories.categories); | |||
| const dimensions = useScreenDimensions(); | |||
| const { t } = useTranslation(); | |||
| const handleSubmit = (values) => { | |||
| props.handleNext(values); | |||
| @@ -23,23 +31,37 @@ const FirstPartCreateOffer = (props) => { | |||
| initialValues: { | |||
| nameOfProduct: "", | |||
| description: "", | |||
| location: "", | |||
| category: "", | |||
| subcategory: "", | |||
| }, | |||
| validationSchema: Yup.object().shape({ | |||
| nameOfProduct: Yup.string().required(t("login.nameOfProductRequired")), | |||
| description: Yup.string().required(t("login.descriptionRequired")).min(8), | |||
| location: Yup.string().oneOf(locations.map((l) => l.city)), | |||
| category: Yup.string().oneOf(categories.map((c) => c.name)), | |||
| // subcategory: Yup.string().oneOf( | |||
| // subcat[0]?.subcategories ? subcat[0].subcategories : [] | |||
| // ), | |||
| }), | |||
| onSubmit: handleSubmit, | |||
| validateOnBlur: true, | |||
| enableReinitialize: true, | |||
| }); | |||
| const handleSubcategories = (category) => { | |||
| const filtered = categories.filter((cat) => cat.name === category); | |||
| setSubcat(filtered); | |||
| }; | |||
| return ( | |||
| <CreateOfferFormContainer component="form" onSubmit={formik.handleSubmit}> | |||
| {/* <Backdrop position="absolute" isLoading={isLoading} /> */} | |||
| <FieldLabel leftText={"NASLOV"} /> | |||
| <FieldLabel leftText={t("offer.title")} /> | |||
| <TitleField | |||
| name="nameOfProduct" | |||
| placeholder={"Naziv proizvoda..."} | |||
| placeholder={t("offer.productName")} | |||
| italicPlaceholder | |||
| margin="normal" | |||
| value={formik.values.nameOfProduct} | |||
| @@ -50,44 +72,91 @@ const FirstPartCreateOffer = (props) => { | |||
| fullWidth | |||
| /> | |||
| <FieldLabel leftText={"OPIS PROIZVODA"} /> | |||
| <DescriptionField | |||
| name="description" | |||
| placeholder={"Opis..."} | |||
| margin="normal" | |||
| italicPlaceholder | |||
| value={formik.values.description} | |||
| onChange={formik.handleChange} | |||
| error={formik.touched.description && formik.errors.description} | |||
| helperText={formik.touched.description && formik.errors.description} | |||
| fullWidth | |||
| multiline | |||
| minRows={4} | |||
| height={"100px"} | |||
| /> | |||
| <FieldLabel leftText={t("offer.productDescription")} /> | |||
| {dimensions.width > 600 ? ( | |||
| <DescriptionField | |||
| name="description" | |||
| placeholder={t("offer.description")} | |||
| margin="normal" | |||
| italicPlaceholder | |||
| value={formik.values.description} | |||
| onChange={formik.handleChange} | |||
| error={formik.touched.description && formik.errors.description} | |||
| helperText={formik.touched.description && formik.errors.description} | |||
| fullWidth | |||
| multiline | |||
| minRows={4} | |||
| height={"100px"} | |||
| /> | |||
| ) : ( | |||
| <DescriptionField | |||
| name="description" | |||
| placeholder={t("offer.description")} | |||
| margin="normal" | |||
| italicPlaceholder | |||
| value={formik.values.description} | |||
| onChange={formik.handleChange} | |||
| error={formik.touched.description && formik.errors.description} | |||
| helperText={formik.touched.description && formik.errors.description} | |||
| fullWidth | |||
| /> | |||
| )} | |||
| <FieldLabel leftText={"LOKACIJA"} /> | |||
| <SelectField defaultValue={1}> | |||
| <Option value={1}>Opcija 1</Option> | |||
| <Option value={2}>Opcija 2</Option> | |||
| <Option value={3}>Opcija 3</Option> | |||
| <Option value={4}>Opcija 4</Option> | |||
| <FieldLabel leftText={t("offer.location")} /> | |||
| <SelectField | |||
| defaultValue="default" | |||
| onChange={(value) => { | |||
| formik.setFieldValue("location", value.target.value.city); | |||
| }} | |||
| > | |||
| <Option value="default">{t("offer.choseLocation")}</Option> | |||
| {locations.map((loc) => { | |||
| return ( | |||
| <Option key={loc._if} value={loc}> | |||
| {loc.city} | |||
| </Option> | |||
| ); | |||
| })} | |||
| </SelectField> | |||
| <FieldLabel leftText={"KATEGORIJA"} /> | |||
| <SelectField defaultValue={1}> | |||
| <Option value={1}>Opcija 1</Option> | |||
| <Option value={2}>Opcija 2</Option> | |||
| <Option value={3}>Opcija 3</Option> | |||
| <Option value={4}>Opcija 4</Option> | |||
| <FieldLabel leftText={t("offer.category")} /> | |||
| <SelectField | |||
| defaultValue="default" | |||
| onChange={(value) => { | |||
| formik.setFieldValue("category", value.target.value.name); | |||
| }} | |||
| > | |||
| <Option value="default">{t("offer.choseCategory")}</Option> | |||
| {categories.map((cat, i) => { | |||
| return ( | |||
| <Option | |||
| key={i} | |||
| value={cat} | |||
| onClick={() => handleSubcategories(cat.name)} | |||
| > | |||
| {cat.name} | |||
| </Option> | |||
| ); | |||
| })} | |||
| </SelectField> | |||
| <FieldLabel leftText={"PODKATEGORIJA"} /> | |||
| <SelectField defaultValue={1}> | |||
| <Option value={1}>Opcija 1</Option> | |||
| <Option value={2}>Opcija 2</Option> | |||
| <Option value={3}>Opcija 3</Option> | |||
| <Option value={4}>Opcija 4</Option> | |||
| <FieldLabel leftText={t("offer.subcategory")} /> | |||
| <SelectField | |||
| defaultValue="default" | |||
| onChange={(value) => { | |||
| formik.setFieldValue("subcategory", value.target.value.name); | |||
| }} | |||
| > | |||
| <Option value="default">{t("offer.choseSubcategory")}</Option> | |||
| {subcat?.length > 0 && | |||
| subcat[0]?.subcategories && | |||
| subcat[0].subcategories.map((sub, i) => { | |||
| return ( | |||
| <Option key={i} value={sub}> | |||
| {sub.name} | |||
| </Option> | |||
| ); | |||
| })} | |||
| </SelectField> | |||
| <NextButton | |||
| @@ -102,7 +171,7 @@ const FirstPartCreateOffer = (props) => { | |||
| // formik.values.password.length === 0 | |||
| // } | |||
| > | |||
| NASTAVI | |||
| {t("offer.continue")} | |||
| </NextButton> | |||
| </CreateOfferFormContainer> | |||
| ); | |||
| @@ -36,8 +36,7 @@ export const CreateOfferDescription = styled(Typography)` | |||
| `; | |||
| export const CreateOfferFormContainer = styled(Box)` | |||
| width: 335px; | |||
| height: 700px; | |||
| padding-top: 20px; | |||
| padding: 20px 0 35px 0; | |||
| `; | |||
| export const FieldLabel = styled(Label)` | |||
| position: relative; | |||
| @@ -50,13 +49,17 @@ export const FieldLabel = styled(Label)` | |||
| cursor: auto; | |||
| letter-spacing: 0.2px; | |||
| } | |||
| ` | |||
| `; | |||
| export const DescriptionField = styled(TextField)` | |||
| margin-bottom: 4px; | |||
| ` | |||
| export const TitleField = styled(TextField)` | |||
| ` | |||
| `; | |||
| export const TitleField = styled(TextField)``; | |||
| export const NextButton = styled(PrimaryButton)` | |||
| margin-top: 16px; | |||
| ` | |||
| @media screen and (max-width: 600px) { | |||
| width: 332px; | |||
| position: absolute; | |||
| bottom: 20px; | |||
| } | |||
| `; | |||
| @@ -4,18 +4,25 @@ import { | |||
| CreateOfferFormContainer, | |||
| FieldLabel, | |||
| Scroller, | |||
| // ImageListStyled, | |||
| SupportedFormats, | |||
| InputButtonContainer, | |||
| } from "./SecondPartCreateOffer.styled"; | |||
| import ImagePicker from "../../../ImagePicker/ImagePicker"; | |||
| // import Select from "../../../Select/Select"; | |||
| 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"; | |||
| import selectedTheme from "../../../../themes"; | |||
| import { conditionSelectEnum } from "../../../../enums/conditionEnum"; | |||
| import { useFormik } from "formik"; | |||
| import * as Yup from "yup"; | |||
| const SecondPartCreateOffer = () => { | |||
| const [images, setImages] = useState([null, null, null]); // 3 images | |||
| const numberOfImages = 3; | |||
| const SecondPartCreateOffer = (props) => { | |||
| const [images, setImages] = useState( | |||
| Array.apply(null, Array(numberOfImages)).map(() => {}) | |||
| ); // 3 images | |||
| const setImage = (index, image) => { | |||
| setImages((prevState) => { | |||
| let newState = [...prevState]; | |||
| @@ -23,9 +30,30 @@ const SecondPartCreateOffer = () => { | |||
| return [...newState]; | |||
| }); | |||
| }; | |||
| const { t } = useTranslation(); | |||
| let imagesEmpty = 0; | |||
| images.forEach(item => { | |||
| if (item === null || item === undefined) imagesEmpty++; | |||
| }) | |||
| const handleSubmit = (values) => { | |||
| props.handleNext(values); | |||
| }; | |||
| const formik = useFormik({ | |||
| initialValues: { | |||
| images: images, | |||
| condition: "", | |||
| }, | |||
| validationSchema: Yup.object().shape({}), | |||
| onSubmit: handleSubmit, | |||
| validateOnBlur: true, | |||
| enableReinitialize: true, | |||
| }); | |||
| return ( | |||
| <CreateOfferFormContainer> | |||
| <CreateOfferFormContainer component="form" onSubmit={formik.handleSubmit}> | |||
| <Scroller> | |||
| {images.map((item, index) => ( | |||
| <ImagePicker | |||
| @@ -33,43 +61,52 @@ const SecondPartCreateOffer = () => { | |||
| image={item} | |||
| setImage={(image) => setImage(index, image)} | |||
| deleteImage={() => setImage(index, null)} | |||
| showDeleteIcon | |||
| /> | |||
| ))} | |||
| </Scroller> | |||
| <FieldLabel leftText="STANJE" /> | |||
| <SelectField defaultValue={conditionSelectEnum.NEW.value}> | |||
| {Object.keys(conditionSelectEnum).map((key) => { | |||
| var item = conditionSelectEnum[key]; | |||
| return ( | |||
| <Option value={item.value} key={item.value}> | |||
| <SelectText>{item.mainText}</SelectText> | |||
| <SelectAltText>{item.altText}</SelectAltText> | |||
| </Option> | |||
| ); | |||
| })} | |||
| </SelectField> | |||
| <SupportedFormats> | |||
| <Trans i18nKey="offer.supportedImagesFormats" /> | |||
| </SupportedFormats> | |||
| <InputButtonContainer> | |||
| <FieldLabel leftText={t("offer.condition")} /> | |||
| <SelectField | |||
| defaultValue="default" | |||
| onChange={(value) => { | |||
| formik.setFieldValue("condition", value.target.value); | |||
| }} | |||
| > | |||
| <Option value="default">{t("offer.choseCondition")}</Option> | |||
| {Object.keys(conditionSelectEnum).map((key) => { | |||
| var item = conditionSelectEnum[key]; | |||
| return ( | |||
| <Option value={item.mainText} key={item.value}> | |||
| <SelectText>{item.mainText}</SelectText> | |||
| <SelectAltText>{item.altText}</SelectAltText> | |||
| </Option> | |||
| ); | |||
| })} | |||
| </SelectField> | |||
| <NextButton | |||
| type="submit" | |||
| variant="contained" | |||
| height="48px" | |||
| fullWidth | |||
| buttoncolor={selectedTheme.primaryPurple} | |||
| textcolor="white" | |||
| // disabled={ | |||
| // formik.values.username.length === 0 || | |||
| // formik.values.password.length === 0 | |||
| // } | |||
| > | |||
| NASTAVI | |||
| </NextButton> | |||
| <NextButton | |||
| type="submit" | |||
| variant="contained" | |||
| height="48px" | |||
| fullWidth | |||
| buttoncolor={selectedTheme.primaryPurple} | |||
| textcolor="white" | |||
| disabled={imagesEmpty === numberOfImages} | |||
| > | |||
| {t("offer.continue")} | |||
| </NextButton> | |||
| </InputButtonContainer> | |||
| </CreateOfferFormContainer> | |||
| ); | |||
| }; | |||
| SecondPartCreateOffer.propTypes = { | |||
| children: PropTypes.node, | |||
| handleOffer: PropTypes.func, | |||
| handleNext: PropTypes.func, | |||
| }; | |||
| export default SecondPartCreateOffer; | |||
| @@ -1,29 +1,15 @@ | |||
| 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: 350px; | |||
| height: 700px; | |||
| padding-top: 20px; | |||
| margin-top: 20px; | |||
| position: relative; | |||
| `; | |||
| 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; | |||
| @@ -36,19 +22,25 @@ export const FieldLabel = styled(Label)` | |||
| letter-spacing: 0.2px; | |||
| } | |||
| `; | |||
| export const InputButtonContainer = styled(Box)` | |||
| width: 332px; | |||
| margin: 25px auto; | |||
| display: flex; | |||
| flex-direction: column; | |||
| justify-content: center; | |||
| `; | |||
| export const Scroller = styled(HorizontalScroller)` | |||
| min-width: 640px; | |||
| min-width: 100%; | |||
| position: relative; | |||
| 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: 0px; */ | |||
| `; | |||
| @@ -0,0 +1,41 @@ | |||
| import React from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { CreateOfferFormContainer, PreviewCard } from "./ThirdPartCreateOffer.styled"; | |||
| const ThirdPartCreateOffer = (props) => { | |||
| const offer = { | |||
| offer: { | |||
| category: { | |||
| name: props.informations.category, | |||
| }, | |||
| subcategory: props.informations.subcategory, | |||
| condition: props.informations.condition, | |||
| _created: new Date().toString(), | |||
| images: props.informations.images.filter(item => item !== undefined), | |||
| name: props.informations.nameOfProduct, | |||
| description: props.informations.description | |||
| } | |||
| } | |||
| const handleSubmit = (e) => { | |||
| e.preventDefault(); | |||
| props.handleSubmitOffer(); | |||
| }; | |||
| return ( | |||
| <CreateOfferFormContainer component="form" onSubmit={handleSubmit}> | |||
| <PreviewCard | |||
| offer={offer} | |||
| showBarterButton={false} | |||
| showPublishButton | |||
| /> | |||
| </CreateOfferFormContainer> | |||
| ); | |||
| }; | |||
| ThirdPartCreateOffer.propTypes = { | |||
| children: PropTypes.any, | |||
| handleSubmitOffer: PropTypes.func, | |||
| informations: PropTypes.object, | |||
| }; | |||
| export default ThirdPartCreateOffer; | |||
| @@ -0,0 +1,12 @@ | |||
| import { Box } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import ItemDetailsCard from "../../ItemDetailsCard/ItemDetailsCard"; | |||
| export const CreateOfferFormContainer = styled(Box)` | |||
| padding-top: 20px; | |||
| margin-top: 20px; | |||
| width:100%; | |||
| `; | |||
| export const PreviewCard = styled(ItemDetailsCard)` | |||
| ` | |||
| @@ -110,7 +110,11 @@ const FilterCard = (props) => { | |||
| <FilterCheckboxDropdown | |||
| searchPlaceholder={t("filters.location.placeholder")} | |||
| data={[...filters.locations]} | |||
| filters={[...filters.selectedLocations]} | |||
| filters={ | |||
| filters?.selectedLocations?.length > 0 | |||
| ? [...filters.selectedLocations] | |||
| : [] | |||
| } | |||
| icon={<Location />} | |||
| title={t("filters.location.title")} | |||
| setItemsSelected={filters.setSelectedLocations} | |||
| @@ -37,12 +37,20 @@ const FilterCheckboxDropdown = (props) => { | |||
| } | |||
| }, [toSearch]); | |||
| useEffect(() => { | |||
| if (props.filters?.length > 0) { | |||
| setIsOpened(true) | |||
| } | |||
| }, [props.filters]) | |||
| const handleChange = (item) => { | |||
| console.log(item); | |||
| if (props.oneValueAllowed) { | |||
| props.setItemsSelected([item]); | |||
| } else { | |||
| if (props.filters.find(itemInList => itemInList.city.toString() === item.city.toString())) { | |||
| props.setItemsSelected([...props.filters.filter((p) => p.city.toString() !== item.city.toString())]); | |||
| if (props.filters.find(itemInList => itemInList?.city?.toString() === item?.city?.toString())) { | |||
| props.setItemsSelected([...props.filters.filter((p) => p?.city?.toString() !== item?.city?.toString())]); | |||
| } else { | |||
| props.setItemsSelected([...props.filters, item]); | |||
| } | |||
| @@ -71,6 +79,7 @@ const FilterCheckboxDropdown = (props) => { | |||
| toggleIconClosed={<DropdownDown />} | |||
| toggleIconOpened={<DropdownUp />} | |||
| fullWidth | |||
| open={isOpened} | |||
| setIsOpened={setIsOpened} | |||
| toggleIconStyles={{ | |||
| backgroundColor: isOpened | |||
| @@ -83,7 +92,7 @@ const FilterCheckboxDropdown = (props) => { | |||
| {props.filters.map((item) => ( | |||
| <SelectedItem key={item.city} onClick={() => handleDelete(item)}> | |||
| { | |||
| data.find((p) => p.city.toString() === item.city.toString()) | |||
| data.find((p) => p?.city?.toString() === item?.city?.toString()) | |||
| ?.city | |||
| } | |||
| <Close style={{ position: "relative", top: "3px" }} /> | |||
| @@ -124,7 +133,7 @@ const FilterCheckboxDropdown = (props) => { | |||
| value={item} | |||
| checked={props.filters.find( | |||
| (itemInList) => | |||
| itemInList.city.toString() === item.city.toString() | |||
| itemInList?.city?.toString() === item?.city?.toString() | |||
| ) ? true : false} | |||
| onChange={() => handleChange(item)} | |||
| fullWidth | |||
| @@ -34,6 +34,14 @@ const FilterRadioDropdown = (props) => { | |||
| } | |||
| }, [toSearch]); | |||
| useEffect(() => { | |||
| if (props.selected?._id !== 0 && props.selected !== null && props.selected !== undefined) { | |||
| setIsOpened(true); | |||
| } | |||
| }, [props.selected]) | |||
| console.log(props.selected) | |||
| const handleClear = () => { | |||
| setToSearch(""); | |||
| }; | |||
| @@ -54,7 +62,7 @@ const FilterRadioDropdown = (props) => { | |||
| toggleIconClosed={<DropdownDown />} | |||
| toggleIconOpened={<DropdownUp />} | |||
| fullWidth | |||
| open={props.open} | |||
| open={isOpened} | |||
| disabled={props.disabled} | |||
| setIsOpened={handleOpen} | |||
| toggleIconStyles={{ | |||
| @@ -1,4 +1,4 @@ | |||
| import React, { useEffect } from "react"; | |||
| import React from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { | |||
| CheckButton, | |||
| @@ -16,76 +16,99 @@ import { | |||
| OfferDetails, | |||
| OfferImage, | |||
| Scroller, | |||
| PublishButtonContainer, | |||
| } from "./ItemDetailsCard.styled"; | |||
| import { NextButton } from "../CreateOfferCard/FirstPart/FirstPartCreateOffer.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"; | |||
| const ItemDetailsCard = (props) => { | |||
| const offer = props.offer; | |||
| const dateCreated = new Date(offer?.offer?._created); | |||
| const dayCreated = dateCreated.getDate() < 10 ? "0" + dateCreated.getDate() : dateCreated.getDate(); | |||
| const monthCreated = dateCreated.getMonth() < 10 ? "0" + (dateCreated.getMonth() + 1) : (dateCreated.getMonth() + 1); | |||
| 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(); | |||
| console.log(offer); | |||
| // console.log(new Date(props.offer.offer._created)) | |||
| useEffect(() => { | |||
| console.log(props.offer); | |||
| },[props.offer]); | |||
| return ( | |||
| <ItemDetailsCardContainer sponsored={props.sponsored.toString()} halfwidth={props.halfwidth ? 1 : 0}> | |||
| <ItemDetailsCardContainer | |||
| sponsored={props.sponsored.toString()} | |||
| halfwidth={props.halfwidth ? 1 : 0} | |||
| className={props.className} | |||
| > | |||
| <OfferInfo> | |||
| <Info> | |||
| <InfoGroup> | |||
| <InfoIcon color={selectedTheme.iconStrokeColor} component="span" size="16px"> | |||
| <InfoIcon | |||
| color={selectedTheme.iconStrokeColor} | |||
| component="span" | |||
| size="16px" | |||
| > | |||
| <Category width={"14px"} /> | |||
| </InfoIcon> | |||
| <InfoText>{offer?.offer?.category?.name}</InfoText> | |||
| <InfoText>{offer?.offer?.category?.name}</InfoText> | |||
| </InfoGroup> | |||
| <InfoGroup> | |||
| <InfoIcon color={selectedTheme.iconStrokeColor} component="span" size="16px"> | |||
| <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> | |||
| <InfoText>{offer?.offer?.subcategory}</InfoText> | |||
| </InfoGroup> | |||
| <InfoGroup> | |||
| <InfoIcon color={"black"} component="span" size="12px" last> | |||
| <Eye width={"18px"} height={"20px"} /> | |||
| <InfoIcon | |||
| color={selectedTheme.iconStrokeColor} | |||
| component="span" | |||
| size="16px" | |||
| > | |||
| <Quantity width={"22px"} height={"16px"} /> | |||
| </InfoIcon> | |||
| <InfoText>{offer?.offer?.views?.viewers?.length}</InfoText> | |||
| <InfoText>{offer?.offer?.condition}</InfoText> | |||
| </InfoGroup> | |||
| {!props.showPublishButton && ( | |||
| <InfoGroup views> | |||
| <InfoIcon color={"black"} component="span" size="12px" last> | |||
| <Eye width={"18px"} height={"20px"} /> | |||
| </InfoIcon> | |||
| <InfoText>{offer?.offer?.views?.viewers?.length}</InfoText> | |||
| </InfoGroup> | |||
| )} | |||
| </Info> | |||
| <PostDate>Objavljeno: {dayCreated}.{monthCreated}.{yearCreated}</PostDate> | |||
| <PostDate> | |||
| {dayCreated}.{monthCreated}.{yearCreated} | |||
| </PostDate> | |||
| </OfferInfo> | |||
| <Details> | |||
| <Details hasScrollBar={!props.showPublishButton}> | |||
| <OfferTitle>{offer?.offer?.name}</OfferTitle> | |||
| <Scroller> | |||
| {offer?.offer?.images?.map(item => ( | |||
| <OfferImage src={item} key={item} /> | |||
| ))} | |||
| {offer?.offer?.images?.map((item) => { | |||
| return <OfferImage src={item} key={item} />; | |||
| })} | |||
| </Scroller> | |||
| <OfferDetails> | |||
| <OfferDescriptionTitle>Opis:</OfferDescriptionTitle> | |||
| <OfferDescriptionText>{offer?.offer?.description}</OfferDescriptionText> | |||
| <OfferDescriptionText showBarterButton={props.showBarterButton}> | |||
| {offer?.offer?.description} | |||
| </OfferDescriptionText> | |||
| </OfferDetails> | |||
| </Details> | |||
| {!props.halfwidth ? ( | |||
| {!props.halfwidth && !props.showPublishButton ? ( | |||
| <React.Fragment> | |||
| <CheckButton | |||
| variant={props.sponsored ? "contained" : "outlined"} | |||
| buttoncolor={selectedTheme.primaryPurple} | |||
| textcolor={props.sponsored ? "white" : selectedTheme.primaryPurple} | |||
| style={{fontWeight: "600"}} | |||
| style={{ fontWeight: "600" }} | |||
| > | |||
| Trampi | |||
| </CheckButton> | |||
| @@ -93,16 +116,24 @@ const ItemDetailsCard = (props) => { | |||
| ) : ( | |||
| <></> | |||
| )} | |||
| {/* {props.image} | |||
| {props.title} | |||
| {props.description} | |||
| {props.category} | |||
| {props.author} | |||
| {props.location} | |||
| {props.quantity} | |||
| {props.package} | |||
| {props.numberOfViews} */} | |||
| {props.showPublishButton && ( | |||
| <PublishButtonContainer> | |||
| <NextButton | |||
| type="submit" | |||
| variant="contained" | |||
| height="48px" | |||
| width="350px" | |||
| buttoncolor={selectedTheme.primaryPurple} | |||
| textcolor="white" | |||
| // disabled={ | |||
| // formik.values.username.length === 0 || | |||
| // formik.values.password.length === 0 | |||
| // } | |||
| > | |||
| OBJAVI | |||
| </NextButton> | |||
| </PublishButtonContainer> | |||
| )} | |||
| </ItemDetailsCardContainer> | |||
| ); | |||
| }; | |||
| @@ -113,9 +144,12 @@ ItemDetailsCard.propTypes = { | |||
| title: PropTypes.string, | |||
| description: PropTypes.string, | |||
| category: PropTypes.string, | |||
| subcategory: PropTypes.string, | |||
| condition: PropTypes.string, | |||
| showNumberOfViews: PropTypes.bool, | |||
| author: PropTypes.string, | |||
| location: PropTypes.string, | |||
| image: PropTypes.node, | |||
| images: PropTypes.node, | |||
| quantity: PropTypes.number, | |||
| package: PropTypes.string, | |||
| numberOfViews: PropTypes.number, | |||
| @@ -134,6 +168,9 @@ ItemDetailsCard.propTypes = { | |||
| // city:PropTypes.string | |||
| // }) | |||
| // }) | |||
| showBarterButton: PropTypes.bool, | |||
| showPublishButton: PropTypes.bool, | |||
| className: PropTypes.string, | |||
| }; | |||
| ItemDetailsCard.defaultProps = { | |||
| halfwidth: false, | |||
| @@ -21,12 +21,13 @@ export const ItemDetailsCardContainer = styled(Container)` | |||
| padding: 18px; | |||
| max-width: 2000px; | |||
| position: relative; | |||
| padding-bottom: 80px; | |||
| `; | |||
| export const OfferImage = styled.img` | |||
| width: 144px; | |||
| height: 144px; | |||
| border-radius: 4px; | |||
| width: 100%; | |||
| /* padding-bottom: 70px; */ | |||
| @media (max-width: 600px) { | |||
| padding: 10px; | |||
| padding-bottom: 65px; | |||
| } | |||
| `; | |||
| export const OfferInfo = styled(Box)` | |||
| display: flex; | |||
| @@ -43,17 +44,23 @@ export const InfoGroup = styled(Box)` | |||
| flex-direction: row; | |||
| align-items: center; | |||
| gap: 4px; | |||
| @media (max-width: 600px) { | |||
| /* flex: 1; */ | |||
| ${(props) => props.last && `flex: none;`} | |||
| } | |||
| `; | |||
| export const PostDate = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| font-size: 12px; | |||
| color: ${selectedTheme.primaryText}; | |||
| &::before { | |||
| content: "Objavljeno: "; | |||
| @media (max-width: 600px) { | |||
| font-size: 9px; | |||
| font-family: "Open Sans"; | |||
| } | |||
| } | |||
| @media (max-width: 600px) { | |||
| display: none; | |||
| position: absolute; | |||
| bottom: 23px; | |||
| left: 18px; | |||
| width: 70px; | |||
| } | |||
| `; | |||
| export const Info = styled(Box)` | |||
| @@ -64,6 +71,9 @@ export const Info = styled(Box)` | |||
| gap: 0; | |||
| justify-content: space-between; | |||
| margin-bottom: 15px; | |||
| max-width: 92%; | |||
| position: relative; | |||
| left: 5px; | |||
| } | |||
| `; | |||
| export const InfoIcon = styled(Box)` | |||
| @@ -83,9 +93,23 @@ export const OfferTitle = styled(Typography)` | |||
| color: ${selectedTheme.primaryPurple}; | |||
| font-weight: 700; | |||
| font-size: 24px; | |||
| padding: 0 72px; | |||
| @media (max-width: 600px) { | |||
| padding: 0 60px; | |||
| @media screen and (max-width: 600px) { | |||
| padding: 0; | |||
| font-size: 18px; | |||
| } | |||
| `; | |||
| export const OfferImage = styled.img` | |||
| min-width: 144px; | |||
| min-height: 144px; | |||
| width: 144px; | |||
| height: 144px; | |||
| margin-right: 20px; | |||
| object-fit: cover; | |||
| @media screen and (max-width: 600px) { | |||
| min-width: 144px; | |||
| margin-right: 13px; | |||
| } | |||
| `; | |||
| export const OfferAuthor = styled(Box)` | |||
| @@ -110,7 +134,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; | |||
| @media (max-width: 600px) { | |||
| padding: 0; | |||
| } | |||
| @@ -151,10 +175,18 @@ export const OfferDescriptionText = styled(Box)` | |||
| font-size: 16px; | |||
| color: ${selectedTheme.primaryDarkText}; | |||
| line-height: 22px; | |||
| max-width: calc(100% - 30px); | |||
| max-width: calc(100% - 130px); | |||
| padding-bottom: 20px; | |||
| @media (max-width: 600px) { | |||
| font-size: 14px; | |||
| max-width: 100%; | |||
| } | |||
| /* max-width: calc(100% - 230px); */ | |||
| max-width: ${(props) => props.showBarterButton && "calc(100% - 230px)"}; | |||
| /* overflow: hidden; */ | |||
| /* display: -webkit-box; | |||
| -webkit-line-clamp: 5; | |||
| -webkit-box-orient: vertical; */ | |||
| `; | |||
| export const OfferDescription = styled(Box)` | |||
| flex: 3; | |||
| @@ -186,7 +218,7 @@ export const CheckButton = styled(PrimaryButton)` | |||
| height: 48px; | |||
| position: absolute; | |||
| bottom: 9px; | |||
| right: 9px; | |||
| right: 12px; | |||
| &:hover button { | |||
| background-color: ${selectedTheme.primaryPurple} !important; | |||
| color: white !important; | |||
| @@ -199,11 +231,36 @@ export const Details = styled(Box)` | |||
| display: flex; | |||
| flex-direction: column; | |||
| gap: 12px; | |||
| ${(props) => props.hasScrollBar && `max-height: 400px;`} | |||
| overflow-y: auto; | |||
| overflow-x: hidden; | |||
| ::-webkit-scrollbar { | |||
| width: 5px; | |||
| } | |||
| ::-webkit-scrollbar-thumb { | |||
| background: #c4c4c4; | |||
| border-radius: 3px; | |||
| } | |||
| @media screen and (max-width: 600px) { | |||
| margin-top: 15px; | |||
| overflow: hidden; | |||
| max-height: none; | |||
| } | |||
| `; | |||
| // export const OfferImage = styled.img` | |||
| // ` | |||
| export const Scroller = styled(HorizontalScroller)` | |||
| & div { | |||
| min-height: 144px; | |||
| min-width: 144px; | |||
| max-width: 100%; | |||
| /* & div { | |||
| margin: 0 9px; | |||
| } | |||
| } */ | |||
| `; | |||
| export const PublishButtonContainer = styled(Box)` | |||
| display: flex; | |||
| justify-content: center; | |||
| margin-bottom: 30px; | |||
| `; | |||
| @@ -90,6 +90,7 @@ export const OfferTitle = styled(Typography)` | |||
| color: ${selectedTheme.primaryPurple}; | |||
| font-weight: 700; | |||
| font-size: 24px; | |||
| width: calc(100% - 120px); | |||
| cursor: pointer; | |||
| @media (max-width: 550px) { | |||
| font-size: 18px; | |||
| @@ -54,12 +54,14 @@ import FilterCard from "../Cards/FilterCard/FilterCard"; | |||
| import { useQueryString } from "../../hooks/useQueryString"; | |||
| import { convertQueryStringFrontend } from "../../util/helpers/queryHelpers"; | |||
| import { fetchMineProfile } from "../../store/actions/profile/profileActions"; | |||
| import CreateOffer from "../Cards/CreateOfferCard/CreateOffer"; | |||
| const Header = () => { | |||
| const [openDrawer, setOpenDrawer] = useState(false); | |||
| const [openFilters, setOpenFilters] = useState(false); | |||
| const [showSearchBar, setShowSearchBar] = useState(true); | |||
| const [numberOfFilters, setNumberOfFilters] = useState(0); | |||
| const [showCreateOfferModal, setShowCreateOfferModal] = useState(false); | |||
| const { t } = useTranslation(); | |||
| const theme = useTheme(); | |||
| const searchRef = useRef(null); | |||
| @@ -111,6 +113,16 @@ const Header = () => { | |||
| } | |||
| }); | |||
| const closeCreateOfferModal = () => { | |||
| setShowCreateOfferModal(false); | |||
| }; | |||
| if (showCreateOfferModal) { | |||
| document.body.style.overflow = "hidden"; | |||
| } else { | |||
| document.body.style.overflow = "auto"; | |||
| } | |||
| const [postsPopoverOpen, setPostsPopoverOpen] = useState(false); | |||
| const [postsAnchorEl, setPostsAnchorEl] = useState(null); | |||
| @@ -140,6 +152,12 @@ const Header = () => { | |||
| setShouldShow(shouldShowHeader); | |||
| }, [location.pathname, user, routeMatch]); | |||
| useEffect(() => { | |||
| setUserPopoverOpen(false); | |||
| setMsgPopoverOpen(false); | |||
| setPostsPopoverOpen(false); | |||
| }, [location.pathname]) | |||
| const handleToggleDrawer = () => { | |||
| setOpenDrawer(!openDrawer); | |||
| }; | |||
| @@ -163,7 +181,9 @@ const Header = () => { | |||
| fullWidth | |||
| buttoncolor={selectedTheme.primaryYellow} | |||
| textcolor="black" | |||
| onClick={() => handleToggleDrawer()} | |||
| onClick={() => { | |||
| handleToggleDrawer(); | |||
| }} | |||
| > | |||
| {t("header.addOffer")} | |||
| </PrimaryButton> | |||
| @@ -247,7 +267,6 @@ const Header = () => { | |||
| searchRef.current.removeEventListener("keyup", listener); | |||
| }; | |||
| const handleSearch = (value) => { | |||
| console.log(value); | |||
| if (value.length === 0) return; | |||
| search.searchOffers(value); | |||
| }; | |||
| @@ -270,7 +289,7 @@ const Header = () => { | |||
| elevation={0} | |||
| position="fixed" | |||
| // positionFixed | |||
| sx={{ backgroundColor: "white" }} | |||
| sx={{ backgroundColor: "white", zIndex: "80" }} | |||
| > | |||
| <Toolbar> | |||
| <ToolsContainer> | |||
| @@ -319,6 +338,7 @@ const Header = () => { | |||
| onClick={() => { | |||
| setUserPopoverOpen(false); | |||
| setUserAnchorEl(null); | |||
| setShowCreateOfferModal(true); | |||
| }} | |||
| > | |||
| {t("header.addOffer")} | |||
| @@ -464,12 +484,16 @@ const Header = () => { | |||
| responsiveOpen={openFilters} | |||
| closeResponsive={toggleFilters} | |||
| /> | |||
| {showCreateOfferModal && ( | |||
| <CreateOffer closeCreateOfferModal={closeCreateOfferModal} /> | |||
| )} | |||
| </HeaderContainer> | |||
| ); | |||
| }; | |||
| Header.propTypes = { | |||
| isGrid: PropTypes.bool, | |||
| showModalHandler: PropTypes.func, | |||
| }; | |||
| export default Header; | |||
| @@ -63,8 +63,9 @@ export const AddFile = styled.input` | |||
| export const ImageUploaded = styled.img` | |||
| width: 144px; | |||
| height: 144px; | |||
| border-radius: 100px; | |||
| object-fit: scale-down; | |||
| /* border-radius: 100px; */ | |||
| /* object-fit: scale-down; */ | |||
| object-fit: cover; | |||
| z-index: 1; | |||
| `; | |||
| export const ImageOverlay = styled(Box)` | |||
| @@ -73,10 +74,10 @@ export const ImageOverlay = styled(Box)` | |||
| left: 0; | |||
| width: 100%; | |||
| height: 100%; | |||
| background-color: rgba(0,0,0,0.5); | |||
| 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); | |||
| width: 100px; | |||
| @@ -97,7 +98,7 @@ export const Trash = styled(TrashIcon)` | |||
| export const Tools = styled(Box)` | |||
| position: absolute; | |||
| padding-top: 44px; | |||
| padding-left: ${props => props.showDeleteIcon ? "16px" : "45px"}; | |||
| padding-left: ${(props) => (props.showDeleteIcon ? "16px" : "45px")}; | |||
| z-index: 4; | |||
| flex-direction: row; | |||
| display: flex; | |||
| @@ -1,7 +1,7 @@ | |||
| import React, { useMemo } from 'react'; | |||
| import Header from "./Header/Header"; | |||
| import { useSelector } from 'react-redux'; | |||
| 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'; | |||
| @@ -29,4 +29,4 @@ const ItemDetails = () => { | |||
| ) | |||
| } | |||
| export default ItemDetails; | |||
| export default ItemDetails; | |||
| @@ -25,7 +25,6 @@ import { useHistory } from "react-router-dom"; | |||
| const ItemDetailsHeaderCard = (props) => { | |||
| const history = useHistory(); | |||
| console.log("header offer: ", props.offer); | |||
| const offer = props.offer; | |||
| if (!props.offer) { | |||
| return <div>Loading...</div>; | |||
| @@ -1,26 +1,30 @@ | |||
| import React from 'react'; | |||
| import PropTypes from 'prop-types'; | |||
| import { Backdrop, CircularProgress } from '@mui/material'; | |||
| import { alpha } from '@mui/system'; | |||
| import React from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { Backdrop } from "@mui/material"; | |||
| // import { alpha } from "@mui/system"; | |||
| const BackdropComponent = ({ position = 'fixed', isLoading }) => ( | |||
| <Backdrop | |||
| sx={{ | |||
| // 'fixed' takes whole page, 'absolute' takes whole space of the parent element which needs to have 'relative' position | |||
| position, | |||
| backgroundColor: ({ palette }) => | |||
| alpha(palette.background.default, palette.action.disabledOpacity), | |||
| zIndex: ({ zIndex }) => zIndex.drawer + 1, | |||
| }} | |||
| open={isLoading} | |||
| > | |||
| <CircularProgress /> | |||
| </Backdrop> | |||
| const BackdropComponent = ({ position = "fixed", isLoading, handleClose }) => ( | |||
| <Backdrop | |||
| sx={{ | |||
| // 'fixed' takes whole page, 'absolute' takes whole space of the parent element which needs to have 'relative' position | |||
| position, | |||
| // zIndex: ({ zIndex }) => zIndex.drawer + 1, | |||
| zIndex: 140, | |||
| }} | |||
| open={isLoading} | |||
| onClick={handleClose} | |||
| style={{ | |||
| backgroundColor: "rgba(0,0,0,0.3)", | |||
| }} | |||
| > | |||
| {/* <CircularProgress /> */} | |||
| </Backdrop> | |||
| ); | |||
| BackdropComponent.propTypes = { | |||
| position: PropTypes.oneOf(['fixed', 'absolute']), | |||
| isLoading: PropTypes.bool.isRequired, | |||
| position: PropTypes.oneOf(["fixed", "absolute"]), | |||
| isLoading: PropTypes.bool.isRequired, | |||
| handleClose: PropTypes.func, | |||
| }; | |||
| export default BackdropComponent; | |||
| @@ -0,0 +1,160 @@ | |||
| import React, { useState, useMemo, useContext } from "react"; | |||
| import { | |||
| AppBar, | |||
| Badge, | |||
| Box, | |||
| IconButton, | |||
| Toolbar, | |||
| Typography, | |||
| List, | |||
| ListItem, | |||
| ListItemButton, | |||
| ListItemIcon, | |||
| ListItemText, | |||
| useMediaQuery, | |||
| } from "@mui/material"; | |||
| import { useTheme } from "@mui/system"; | |||
| import MenuOutlinedIcon from "@mui/icons-material/MenuOutlined"; | |||
| import ShoppingBasketIcon from "@mui/icons-material/ShoppingBasket"; | |||
| import Brightness4Icon from "@mui/icons-material/Brightness4"; | |||
| import Brightness7Icon from "@mui/icons-material/Brightness7"; | |||
| import MenuList from "./MenuListComponent"; | |||
| import Drawer from "./DrawerComponent"; | |||
| import { ColorModeContext } from "../../context/ColorModeContext"; | |||
| const NavbarComponent = () => { | |||
| const [openDrawer, setOpenDrawer] = useState(false); | |||
| const theme = useTheme(); | |||
| const matches = useMediaQuery(theme.breakpoints.down("sm")); | |||
| const toggleColorMode = useContext(ColorModeContext); | |||
| const handleToggleDrawer = () => { | |||
| setOpenDrawer(!openDrawer); | |||
| }; | |||
| const drawerContent = useMemo( | |||
| () => ( | |||
| <List> | |||
| <ListItemButton divider onClick={handleToggleDrawer}> | |||
| <ListItemIcon> | |||
| <ListItemText>Link 1</ListItemText> | |||
| </ListItemIcon> | |||
| </ListItemButton> | |||
| <ListItem divider onClick={handleToggleDrawer}> | |||
| <ListItemIcon> | |||
| <ListItemText>Link 2</ListItemText> | |||
| </ListItemIcon> | |||
| </ListItem> | |||
| <ListItem divider onClick={handleToggleDrawer}> | |||
| <ListItemText>Link 3</ListItemText> | |||
| </ListItem> | |||
| <ListItem divider> | |||
| <IconButton onClick={toggleColorMode}> | |||
| <ListItemText>Toggle {theme.palette.mode} mode</ListItemText> | |||
| {theme.palette.mode === "dark" ? ( | |||
| <Brightness7Icon /> | |||
| ) : ( | |||
| <Brightness4Icon /> | |||
| )} | |||
| </IconButton> | |||
| </ListItem> | |||
| </List> | |||
| ), | |||
| [handleToggleDrawer] | |||
| ); | |||
| return ( | |||
| <AppBar | |||
| elevation={2} | |||
| sx={{ backgroundColor: "background.default", position: "relative" }} | |||
| > | |||
| <Toolbar> | |||
| <Box | |||
| component="div" | |||
| sx={{ | |||
| display: "flex", | |||
| justifyContent: "space-between", | |||
| alignItems: "center", | |||
| width: "100%", | |||
| }} | |||
| > | |||
| {matches ? ( | |||
| <Drawer | |||
| open={openDrawer} | |||
| toggleOpen={handleToggleDrawer} | |||
| content={drawerContent} | |||
| /> | |||
| ) : ( | |||
| <Box sx={{ display: "flex" }}> | |||
| <Typography | |||
| variant="h6" | |||
| sx={{ | |||
| marginRight: 3, | |||
| cursor: "pointer", | |||
| color: "text.primary", | |||
| }} | |||
| > | |||
| Link 1 | |||
| </Typography> | |||
| <Typography | |||
| variant="body1" | |||
| sx={{ | |||
| marginRight: 3, | |||
| cursor: "pointer", | |||
| color: "text.primary", | |||
| }} | |||
| > | |||
| Link 2 | |||
| </Typography> | |||
| <Typography | |||
| variant="subtitle1" | |||
| sx={{ | |||
| marginRight: 3, | |||
| cursor: "pointer", | |||
| color: "text.primary", | |||
| }} | |||
| > | |||
| Link 3 | |||
| </Typography> | |||
| </Box> | |||
| )} | |||
| <Box> | |||
| <MenuList /> | |||
| </Box> | |||
| <Box | |||
| sx={{ | |||
| display: "flex", | |||
| justifyContent: "center", | |||
| alignItems: "center", | |||
| }} | |||
| > | |||
| {matches ? ( | |||
| <Box> | |||
| <IconButton onClick={handleToggleDrawer}> | |||
| <MenuOutlinedIcon /> | |||
| </IconButton> | |||
| </Box> | |||
| ) : ( | |||
| <Box> | |||
| <IconButton> | |||
| <Badge badgeContent={3} color="primary"> | |||
| <ShoppingBasketIcon color="action" /> | |||
| </Badge> | |||
| </IconButton> | |||
| <IconButton sx={{ ml: 1 }} onClick={toggleColorMode}> | |||
| {theme.palette.mode === "dark" ? ( | |||
| <Brightness7Icon /> | |||
| ) : ( | |||
| <Brightness4Icon /> | |||
| )} | |||
| </IconButton> | |||
| </Box> | |||
| )} | |||
| </Box> | |||
| </Box> | |||
| </Toolbar> | |||
| </AppBar> | |||
| ); | |||
| }; | |||
| export default NavbarComponent; | |||
| @@ -14,7 +14,7 @@ export const PagingContainer = styled(Box)` | |||
| margin-top: 5px; | |||
| margin-bottom: 10px; | |||
| position: absolute; | |||
| bottom: 0; | |||
| bottom: 15px; | |||
| padding-left: 0; | |||
| padding-right: 0; | |||
| margin: auto; | |||
| @@ -19,21 +19,26 @@ const HeaderPopover = (props) => { | |||
| <HeaderPopoverContainer> | |||
| <PopoverTitle p={2}>{props.title}</PopoverTitle> | |||
| <PopoverList> | |||
| {props.items?.length > 0 ? props.items.map((item, index) => ( | |||
| <PopoverListItem key={index}> | |||
| <PopoverListItemAvatarContainer> | |||
| {props.isProfile ? ( | |||
| <PopoverListItemProfileAvatar alt={item.alt} src={item.src} /> | |||
| ) : ( | |||
| <PopoverListItemAvatar alt={item.alt} src={item.src} /> | |||
| )} | |||
| </PopoverListItemAvatarContainer> | |||
| <PopoverListItemTextContainer | |||
| primary={item.title} | |||
| secondary={item.text} | |||
| ></PopoverListItemTextContainer> | |||
| </PopoverListItem> | |||
| )) : ( | |||
| {props.items?.length > 0 ? ( | |||
| props.items.map((item, index) => ( | |||
| <PopoverListItem key={index}> | |||
| <PopoverListItemAvatarContainer> | |||
| {props.isProfile ? ( | |||
| <PopoverListItemProfileAvatar alt={item.alt} src={item.src} onClick={item?.onClick} /> | |||
| ) : ( | |||
| <PopoverListItemAvatar alt={item.alt} src={item.src} onClick={item?.onClick} /> | |||
| )} | |||
| </PopoverListItemAvatarContainer> | |||
| <PopoverListItemTextContainer | |||
| primaryTypographyProps={{ | |||
| onClick: item.onClick | |||
| }} | |||
| primary={item.title} | |||
| secondary={item.text} | |||
| ></PopoverListItemTextContainer> | |||
| </PopoverListItem> | |||
| )) | |||
| ) : ( | |||
| <PopoverNoItemsText>No items at the moment...</PopoverNoItemsText> | |||
| )} | |||
| </PopoverList> | |||
| @@ -1,70 +1,79 @@ | |||
| import { Avatar, Box, Button, List, ListItem, ListItemAvatar, ListItemText, Typography } from "@mui/material"; | |||
| import { | |||
| Avatar, | |||
| Box, | |||
| Button, | |||
| List, | |||
| ListItem, | |||
| ListItemAvatar, | |||
| ListItemText, | |||
| Typography, | |||
| } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import selectedTheme from "../../../themes"; | |||
| import { ReactComponent as Eye } from "../../../assets/images/svg/eye-striked.svg"; | |||
| import { ProfileAvatar } from "../MyProfile/MyProfile.styled"; | |||
| export const HeaderPopoverContainer = styled(Box)` | |||
| ` | |||
| export const HeaderPopoverContainer = styled(Box)``; | |||
| export const PopoverTitle = styled(Typography)` | |||
| background-color: ${selectedTheme.primaryPurple}; | |||
| color: white; | |||
| width: 100%; | |||
| min-width: 270px; | |||
| font-family: "Open Sans"; | |||
| ` | |||
| background-color: ${selectedTheme.primaryPurple}; | |||
| color: white; | |||
| width: 100%; | |||
| min-width: 270px; | |||
| font-family: "Open Sans"; | |||
| `; | |||
| export const PopoverList = styled(List)` | |||
| width: 100%; | |||
| max-width: 360px; | |||
| background-color: "white"; | |||
| ` | |||
| width: 100%; | |||
| max-width: 360px; | |||
| background-color: "white"; | |||
| `; | |||
| export const PopoverListItem = styled(ListItem)` | |||
| align-items: flex-start; | |||
| ` | |||
| align-items: flex-start; | |||
| `; | |||
| export const PopoverListItemAvatar = styled(Avatar)` | |||
| position: relative; | |||
| top: 4px; | |||
| ` | |||
| position: relative; | |||
| cursor: pointer; | |||
| top: 4px; | |||
| `; | |||
| export const PopoverListItemProfileAvatar = styled(ProfileAvatar)` | |||
| ` | |||
| export const PopoverListItemAvatarContainer = styled(ListItemAvatar)` | |||
| ` | |||
| cursor: pointer; | |||
| `; | |||
| export const PopoverListItemAvatarContainer = styled(ListItemAvatar)``; | |||
| export const PopoverButton = styled(Button)` | |||
| text-decoration: underline; | |||
| color: ${selectedTheme.primaryPurple}; | |||
| font-weight: 500; | |||
| text-align: right; | |||
| height: 20px; | |||
| ` | |||
| text-decoration: underline; | |||
| color: ${selectedTheme.primaryPurple}; | |||
| font-weight: 500; | |||
| text-align: right; | |||
| height: 20px; | |||
| `; | |||
| export const PopoverListItemTextContainer = styled(ListItemText)` | |||
| & span { | |||
| font-weight: 700; | |||
| color: ${selectedTheme.primaryPurple}; | |||
| } | |||
| & p { | |||
| font-size: 0.81rem; | |||
| & svg { | |||
| position: relative; | |||
| top: 2px; | |||
| } | |||
| & span { | |||
| font-weight: 700; | |||
| color: ${selectedTheme.primaryPurple}; | |||
| cursor: pointer; | |||
| } | |||
| & p { | |||
| font-size: 0.81rem; | |||
| & svg { | |||
| position: relative; | |||
| top: 2px; | |||
| } | |||
| ` | |||
| } | |||
| `; | |||
| export const EyeIcon = styled(Eye)` | |||
| & path { | |||
| stroke: ${selectedTheme.primaryYellow}; | |||
| } | |||
| ` | |||
| & path { | |||
| stroke: ${selectedTheme.primaryYellow}; | |||
| } | |||
| `; | |||
| export const PopoverButtonsContainer = styled(Box)` | |||
| flex-direction: column; | |||
| display: flex; | |||
| align-items: flex-end; | |||
| ` | |||
| flex-direction: column; | |||
| display: flex; | |||
| align-items: flex-end; | |||
| `; | |||
| export const PopoverNoItemsText = styled(Typography)` | |||
| text-align: center; | |||
| width: 100%; | |||
| font-weight: 600; | |||
| padding-top: 5px; | |||
| font-size: 13px; | |||
| font-family: "Open Sans"; | |||
| ` | |||
| text-align: center; | |||
| width: 100%; | |||
| font-weight: 600; | |||
| padding-top: 5px; | |||
| font-size: 13px; | |||
| font-family: "Open Sans"; | |||
| `; | |||
| @@ -21,17 +21,18 @@ import { useDispatch, useSelector } from "react-redux"; | |||
| import { selectMineOffers } from "../../../store/selectors/offersSelectors"; | |||
| import { fetchMineOffers } from "../../../store/actions/offers/offersActions"; | |||
| import { selectProfileName } from "../../../store/selectors/profileSelectors"; | |||
| import { useHistory } from "react-router-dom"; | |||
| export const MyPosts = () => { | |||
| const { t } = useTranslation(); | |||
| const dispatch = useDispatch(); | |||
| const mineOffers = useSelector(selectMineOffers); | |||
| const name = useSelector(selectProfileName); | |||
| const history = useHistory(); | |||
| const [arrayOfMineOffers, setArrayOfMineOffers] = useState([]); | |||
| useEffect(() => { | |||
| dispatch(fetchMineOffers()); | |||
| }, []); | |||
| console.log("mineOffers: ", mineOffers) | |||
| useEffect(() => { | |||
| if (mineOffers?.length > 0) { | |||
| if (mineOffers.length > 1) { | |||
| @@ -40,6 +41,7 @@ export const MyPosts = () => { | |||
| alt: "Photo", | |||
| src: item.images[0], | |||
| title: item.name, | |||
| onClick: () => goToOffer(item._id), | |||
| text: ( | |||
| <React.Fragment> | |||
| <PostsImgSuit /> {name} | |||
| @@ -53,6 +55,7 @@ export const MyPosts = () => { | |||
| alt: "Photo", | |||
| src: item.images[0], | |||
| title: item.name, | |||
| onClick: () => goToOffer(item._id), | |||
| text: ( | |||
| <React.Fragment> | |||
| <PostsImgSuit /> {name} | |||
| @@ -61,10 +64,14 @@ export const MyPosts = () => { | |||
| })) | |||
| ); | |||
| } else { | |||
| setArrayOfMineOffers([]) | |||
| setArrayOfMineOffers([]); | |||
| } | |||
| } | |||
| }, [mineOffers]); | |||
| const goToOffer = (id) => { | |||
| history.push(`/proizvodi/${id}`) | |||
| } | |||
| return ( | |||
| <HeaderPopover | |||
| title={t("header.myOffers")} | |||
| @@ -31,6 +31,7 @@ export const MyProfile = () => { | |||
| alt: "Profile", | |||
| src: `${profile.image}`, | |||
| title: profile.company.name, | |||
| onClick: () => seeMyProfile(), | |||
| text: ( | |||
| <React.Fragment> | |||
| <ProfileImgPIB /> | |||
| @@ -1,34 +1,33 @@ | |||
| import { TextField, Avatar } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import PIB from '@mui/icons-material/AdminPanelSettingsOutlined'; | |||
| import {ReactComponent as Logout} from "../../../assets/images/svg/log-out.svg"; | |||
| import PIB from "@mui/icons-material/AdminPanelSettingsOutlined"; | |||
| import { ReactComponent as Logout } from "../../../assets/images/svg/log-out.svg"; | |||
| export const ProfileImgPIB = styled(PIB)` | |||
| width: 1rem; | |||
| height: 1rem; | |||
| margin-right: .36rem; | |||
| ` | |||
| width: 1rem; | |||
| height: 1rem; | |||
| margin-right: 0.36rem; | |||
| `; | |||
| export const ProfileAvatar = styled(Avatar)` | |||
| width: 63px; | |||
| height: 63px; | |||
| margin-right: 1rem; | |||
| ` | |||
| width: 63px; | |||
| height: 63px; | |||
| margin-right: 1rem; | |||
| `; | |||
| export const SearchInput = styled(TextField)` | |||
| margin-left: 3.8rem; | |||
| background-color: #F4F4F4; | |||
| width: 45%; | |||
| max-width: 100%; | |||
| @media (max-width: 1100px) { | |||
| width: 36%; | |||
| } | |||
| @media (max-width: 900px) { | |||
| width: 54%; | |||
| } | |||
| @media (max-width: 600px) { | |||
| width: 36%; | |||
| } | |||
| ` | |||
| export const LogoutIcon = styled(Logout)` | |||
| ` | |||
| margin-left: 3.8rem; | |||
| background-color: #f4f4f4; | |||
| width: 45%; | |||
| max-width: 100%; | |||
| @media (max-width: 1100px) { | |||
| width: 36%; | |||
| } | |||
| @media (max-width: 900px) { | |||
| width: 54%; | |||
| } | |||
| @media (max-width: 600px) { | |||
| width: 36%; | |||
| } | |||
| `; | |||
| export const LogoutIcon = styled(Logout)``; | |||
| @@ -42,7 +42,6 @@ const ProfileCard = (props) => { | |||
| 100 | |||
| ); | |||
| } | |||
| console.log(profile); | |||
| return ( | |||
| <> | |||
| <ProfileCardContainer> | |||
| @@ -1,39 +1,50 @@ | |||
| import { Box } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import {ReactComponent as DownArrow} from "../../assets/images/svg/arrow-down.svg" | |||
| import { ReactComponent as DownArrow } from "../../assets/images/svg/arrow-down.svg"; | |||
| import selectedTheme from "../../themes"; | |||
| import ScrollContainer from 'react-indiana-drag-scroll' | |||
| import ScrollContainer from "react-indiana-drag-scroll"; | |||
| import { IconButton } from "../Buttons/IconButton/IconButton"; | |||
| export const HorizontalScrollerContainer = styled(Box)` | |||
| display: flex; | |||
| flex: 1; | |||
| flex-direction: row; | |||
| flex-wrap: nowrap; | |||
| overflow: hidden; | |||
| ` | |||
| display: flex; | |||
| flex: 1; | |||
| flex-direction: row; | |||
| flex-wrap: nowrap; | |||
| overflow: hidden; | |||
| padding-right: 5px; | |||
| @media screen and (max-width: 600px) { | |||
| width: 100%; | |||
| } | |||
| @media screen and (max-width: 480px) { | |||
| width: 340px; | |||
| } | |||
| `; | |||
| export const Arrow = styled(IconButton)` | |||
| border: 1px solid ${selectedTheme.primaryPurple}; | |||
| border-radius: 100%; | |||
| min-width: 40px; | |||
| width: 40px; | |||
| height: 40px; | |||
| display: block; | |||
| box-sizing: border-box; | |||
| cursor: pointer; | |||
| padding-left: 8px; | |||
| padding-top: 10px; | |||
| margin-top: auto; | |||
| margin-bottom: auto; | |||
| transition: 0.2s all ease; | |||
| &:hover { | |||
| background-color: ${selectedTheme.primaryPurple}; | |||
| & svg path { | |||
| stroke: white; | |||
| } | |||
| border: 1px solid ${selectedTheme.primaryPurple}; | |||
| border-radius: 100%; | |||
| min-width: 40px; | |||
| width: 40px; | |||
| height: 40px; | |||
| display: block; | |||
| box-sizing: border-box; | |||
| cursor: pointer; | |||
| padding-left: 8px; | |||
| padding-top: 10px; | |||
| margin-top: auto; | |||
| margin-bottom: auto; | |||
| transition: 0.2s all ease; | |||
| &:hover { | |||
| background-color: ${selectedTheme.primaryPurple}; | |||
| & svg path { | |||
| stroke: white; | |||
| } | |||
| ${props => props.disabled && ` | |||
| } | |||
| ${(props) => | |||
| props.disabled && | |||
| ` | |||
| border 1px solid ${selectedTheme.iconStrokeDisabledColor}; | |||
| & svg path { | |||
| stroke: ${selectedTheme.iconStrokeDisabledColor}; | |||
| @@ -41,25 +52,29 @@ export const Arrow = styled(IconButton)` | |||
| } | |||
| `} | |||
| ` | |||
| `; | |||
| export const ListContainer = styled(ScrollContainer)` | |||
| display: flex; | |||
| flex: 1; | |||
| flex-direction: row; | |||
| flex-wrap: nowrap; | |||
| scroll-behavior: smooth; | |||
| margin: 0 18px; | |||
| user-select: none; | |||
| ` | |||
| display: flex; | |||
| flex: 1; | |||
| flex-direction: row; | |||
| flex-wrap: nowrap; | |||
| scroll-behavior: smooth; | |||
| margin: 0 18px; | |||
| user-select: none; | |||
| `; | |||
| export const ArrowIcon = styled(DownArrow)` | |||
| ${props => props.side === 'left' && ` | |||
| ${(props) => | |||
| props.side === "left" && | |||
| ` | |||
| transform: rotate(180deg); | |||
| `} | |||
| width: 18px; | |||
| height: 18px; | |||
| & path { | |||
| ${props => props.disabled && ` | |||
| width: 18px; | |||
| height: 18px; | |||
| & path { | |||
| ${(props) => | |||
| props.disabled && | |||
| ` | |||
| stroke: ${selectedTheme.iconStrokeDisabledColor} | |||
| `} | |||
| } | |||
| ` | |||
| } | |||
| `; | |||
| @@ -1,31 +1,29 @@ | |||
| import React from 'react' | |||
| import PropTypes from 'prop-types' | |||
| import { OptionIcon, OptionStyled } from './Option.styled' | |||
| import React from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { OptionIcon, OptionStyled } from "./Option.styled"; | |||
| const Option = props => { | |||
| const Option = (props) => { | |||
| return ( | |||
| <OptionStyled {...props} value={props.value} > | |||
| {props.startIcon ? ( | |||
| <OptionIcon color={props.color}> | |||
| {props.startIcon} | |||
| </OptionIcon> | |||
| ) :(<> | |||
| </>)} | |||
| {props.children} | |||
| <OptionStyled {...props} value={props.value}> | |||
| {props.startIcon ? ( | |||
| <OptionIcon color={props.color}>{props.startIcon}</OptionIcon> | |||
| ) : ( | |||
| <></> | |||
| )} | |||
| {props.children} | |||
| </OptionStyled> | |||
| ) | |||
| } | |||
| ); | |||
| }; | |||
| Option.propTypes = { | |||
| children: PropTypes.node, | |||
| color: PropTypes.any, | |||
| startIcon: PropTypes.any, | |||
| value: PropTypes.any, | |||
| // selected: PropTypes.bool, | |||
| } | |||
| children: PropTypes.node, | |||
| color: PropTypes.any, | |||
| startIcon: PropTypes.any, | |||
| value: PropTypes.any, | |||
| // selected: PropTypes.bool, | |||
| }; | |||
| Option.defaultProps = { | |||
| // selected: true | |||
| } | |||
| }; | |||
| export default Option | |||
| export default Option; | |||
| @@ -9,6 +9,10 @@ export const StepProgressContainer = styled(Box)` | |||
| position: relative; | |||
| left: 2px; | |||
| width: 100%; | |||
| @media screen and (min-width: 468px) and (max-width: 600px) { | |||
| width: 80%; | |||
| } | |||
| `; | |||
| export const StepLine = styled(Box)` | |||
| @@ -22,12 +26,15 @@ export const StepLine = styled(Box)` | |||
| export const StepBar = styled(Box)` | |||
| flex: 0 0 35px; | |||
| background-color: ${(props) => | |||
| props.done ? selectedTheme.primaryPurple : selectedTheme.primaryDarkGrayText}; | |||
| props.done | |||
| ? selectedTheme.primaryPurple | |||
| : selectedTheme.primaryDarkGrayText}; | |||
| border-radius: 100%; | |||
| font-family: "Open Sans"; | |||
| text-align: center; | |||
| border: 5px solid | |||
| ${(props) => (props.current || props.done ? selectedTheme.primaryPurple : "white")}; | |||
| ${(props) => | |||
| props.current || props.done ? selectedTheme.primaryPurple : "white"}; | |||
| padding-top: 2px; | |||
| line-height: 19px; | |||
| margin-left: -2px; | |||
| @@ -35,7 +42,7 @@ export const StepBar = styled(Box)` | |||
| color: #1d1d1d; | |||
| z-index: 1; | |||
| transition: background-color 1s ease; | |||
| ${props => props.done && `cursor: pointer;`} | |||
| ${(props) => props.done && `cursor: pointer;`} | |||
| `; | |||
| export const Progress = styled(Box)` | |||
| height: 9px; | |||
| @@ -1,6 +1,6 @@ | |||
| import React from "react"; | |||
| import React, { useMemo } from "react"; | |||
| import PropTypes from "prop-types"; | |||
| import { ReviewList, ReviewsBox, ThumbDown, ThumbUp } from "./UserReviewsCard.styled"; | |||
| import { NoReviewsAltText, NoReviewsContainer, NoReviewsText, ReviewList, ReviewsBox, ReviewsHeader, ReviewsTitle, ThumbDown, ThumbUp } from "./UserReviewsCard.styled"; | |||
| import { | |||
| Avatar, | |||
| @@ -10,20 +10,57 @@ import { | |||
| Typography, | |||
| Divider, | |||
| } from "@mui/material"; | |||
| import Mockupdata from "./Mockupdata"; | |||
| // import Mockupdata from "./Mockupdata"; | |||
| import StarBorderIcon from "@mui/icons-material/StarBorder"; | |||
| import selectedTheme from "../../themes"; | |||
| import { useSelector } from "react-redux"; | |||
| import { selectOffer } from "../../store/selectors/offersSelectors"; | |||
| import { selectProfile } from "../../store/selectors/profileSelectors"; | |||
| // import { selectUserId } from "../../store/selectors/loginSelectors"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import UserReviewsSkeleton from "./UserReviewsSkeleton/UserReviewsSkeleton"; | |||
| import useScreenDimensions from "../../hooks/useScreenDimensions"; | |||
| const UserReviewsCard = (props) => { | |||
| var dataMockupdata = JSON.parse(JSON.stringify(Mockupdata)); | |||
| const {t} = useTranslation(); | |||
| // const userId = useSelector(selectUserId); | |||
| const offer = useSelector(selectOffer); | |||
| console.log("user reviews: ", offer); | |||
| const dimensions = useScreenDimensions(); | |||
| const profile = useSelector(selectProfile); | |||
| console.log("offer Reviews: ", offer); | |||
| console.log("profile reviews: ", profile); | |||
| console.log("props.profileReviews: ", props.profileReviews); | |||
| // const profileId = useMemo(() => { | |||
| // if (props.profileReviews) { | |||
| // return profile._id; | |||
| // } | |||
| // return offer?.offer?.userId; | |||
| // }, [props.profileReviews, offer, profile]) | |||
| // const isMyProfile = useMemo(() => { | |||
| // if (userId === profileId) return true; | |||
| // return false; | |||
| // }, [profileId, userId]); | |||
| const lastThreeReviews = useMemo(() => { | |||
| if (props.profileReviews) { | |||
| return []; | |||
| } | |||
| return offer?.companyData?.lastThreeReviews; | |||
| }, [props.profileReviews, offer, profile]) | |||
| const NoReviews = () => { | |||
| return ( | |||
| <NoReviewsContainer> | |||
| <NoReviewsText>{t("reviews.title")}</NoReviewsText> | |||
| <NoReviewsAltText>{t("reviews.altTitle")}</NoReviewsAltText> | |||
| <UserReviewsSkeleton numOfElements={dimensions.width < 600 ? 1 : 2} /> | |||
| </NoReviewsContainer> | |||
| ) | |||
| } | |||
| return ( | |||
| <> | |||
| <ReviewsBox> | |||
| <Grid | |||
| <ReviewsHeader | |||
| container | |||
| direction="row" | |||
| justifyContent="start" | |||
| @@ -31,10 +68,10 @@ const UserReviewsCard = (props) => { | |||
| sx={{ mb: 1.4 }} | |||
| > | |||
| <StarBorderIcon color="action" sx={{ mr: 0.9 }} /> | |||
| <Typography>{props.heading}</Typography> | |||
| </Grid> | |||
| <ReviewsTitle>Ocene</ReviewsTitle> | |||
| </ReviewsHeader> | |||
| <ReviewList> | |||
| {offer?.companyData?.lastThreeReviews?.map((review) => ( | |||
| {lastThreeReviews?.length > 0 ? lastThreeReviews?.map((review) => ( | |||
| <> | |||
| <ListItem | |||
| alignItems="flex-start" | |||
| @@ -81,13 +118,13 @@ const UserReviewsCard = (props) => { | |||
| Uspešna trampa: <b>{review.isSuccessfulSwap}</b> | |||
| </Typography> | |||
| </Grid> | |||
| {review.id < dataMockupdata.length - 1 ? ( | |||
| {review.id < review?.length - 1 ? ( | |||
| <Divider variant="inset" component="li" sx={{ ml: 0 }} /> | |||
| ) : ( | |||
| <></> | |||
| )} | |||
| </> | |||
| ))} | |||
| )) : (<NoReviews></NoReviews>)} | |||
| </ReviewList> | |||
| </ReviewsBox> | |||
| </> | |||
| @@ -97,6 +134,10 @@ const UserReviewsCard = (props) => { | |||
| UserReviewsCard.propTypes = { | |||
| children: PropTypes.node, | |||
| heading: PropTypes.string, | |||
| profileReviews: PropTypes.bool, | |||
| }; | |||
| UserReviewsCard.defaultProps = { | |||
| profileReviews: false, | |||
| } | |||
| export default UserReviewsCard; | |||
| @@ -1,12 +1,37 @@ | |||
| import styled from "styled-components"; | |||
| import { List, Box } from "@mui/material"; | |||
| import { List, Box, Typography, Grid } from "@mui/material"; | |||
| import ThumbUpIcon from "@mui/icons-material/ThumbUp"; | |||
| import ThumbDownIcon from "@mui/icons-material/ThumbDown"; | |||
| import selectedTheme from "../../themes"; | |||
| export const ReviewsBox = styled(Box)` | |||
| width: 100%; | |||
| height: calc(100% - 90px); | |||
| @media (max-width: 1200px) { | |||
| padding: 0 50px; | |||
| } | |||
| @media (max-width: 600px) { | |||
| position: relative; | |||
| top: -45px; | |||
| overflow: hidden; | |||
| height: 350px; | |||
| max-height: 350px; | |||
| padding: 0; | |||
| } | |||
| `; | |||
| export const ReviewsHeader = styled(Grid)` | |||
| @media (max-width: 800px) { | |||
| display: none; | |||
| } | |||
| ` | |||
| export const ReviewsTitle = styled(Typography)` | |||
| font-family: "Open Sans"; | |||
| font-size: 16px; | |||
| @media (max-width: 800px) { | |||
| display: none; | |||
| } | |||
| ` | |||
| export const ReviewList = styled(List)` | |||
| background: white; | |||
| @@ -14,7 +39,9 @@ export const ReviewList = styled(List)` | |||
| border-radius: 4px 0 0 4px; | |||
| height: 100%; | |||
| width: 100%; | |||
| overflow-y: auto; | |||
| border: 1px solid ${selectedTheme.borderNormal}; | |||
| /* overflow-y: auto; */ | |||
| &::-webkit-scrollbar { | |||
| width: 5px; | |||
| } | |||
| @@ -36,3 +63,22 @@ export const ThumbDown = styled(ThumbDownIcon)` | |||
| position: relative; | |||
| left: -8px; | |||
| ` | |||
| export const NoReviewsContainer = styled(Box)` | |||
| ` | |||
| export const NoReviewsText = styled(Typography)` | |||
| color: ${selectedTheme.primaryPurple}; | |||
| font-size: 24px; | |||
| font-family: "Open Sans"; | |||
| text-align: center; | |||
| font-weight: 700; | |||
| width: 100%; | |||
| ` | |||
| export const NoReviewsAltText = styled(Typography)` | |||
| font-size: 12px; | |||
| color: ${selectedTheme.primaryDarkText}; | |||
| font-family: "Open Sans"; | |||
| text-align: center; | |||
| width: 100%; | |||
| margin-bottom: 36px; | |||
| ` | |||
| @@ -0,0 +1,39 @@ | |||
| import React from 'react' | |||
| import PropTypes from 'prop-types' | |||
| import { UserReviewsSkeletonCircle, UserReviewsSkeletonContainer, UserReviewsSkeletonItemsContainer, UserReviewsSkeletonLine, UserReviewsSkeletonLineFifth, UserReviewsSkeletonLineForth, UserReviewsSkeletonLineOne, UserReviewsSkeletonLineSecond, UserReviewsSkeletonLineThird, UserReviewsSkeletonSquare } from './UserReviewsSkeleton.styled' | |||
| const UserReviewsSkeleton = (props) => { | |||
| const array = Array.apply(null, Array(props.numOfElements)).map(() => {}) | |||
| return ( | |||
| <UserReviewsSkeletonContainer> | |||
| {array.map((item, index) => ( | |||
| <UserReviewsSkeletonItemsContainer key={index}> | |||
| <UserReviewsSkeletonLine> | |||
| <UserReviewsSkeletonCircle/> | |||
| <UserReviewsSkeletonLineOne /> | |||
| </UserReviewsSkeletonLine> | |||
| <UserReviewsSkeletonLine> | |||
| <UserReviewsSkeletonSquare /> | |||
| <UserReviewsSkeletonLineSecond /> | |||
| </UserReviewsSkeletonLine> | |||
| <UserReviewsSkeletonLine> | |||
| <UserReviewsSkeletonLineThird /> | |||
| </UserReviewsSkeletonLine> | |||
| <UserReviewsSkeletonLine> | |||
| <UserReviewsSkeletonLineForth /> | |||
| </UserReviewsSkeletonLine> | |||
| <UserReviewsSkeletonLine> | |||
| <UserReviewsSkeletonLineFifth /> | |||
| </UserReviewsSkeletonLine> | |||
| </UserReviewsSkeletonItemsContainer> | |||
| ))} | |||
| </UserReviewsSkeletonContainer> | |||
| ) | |||
| } | |||
| UserReviewsSkeleton.propTypes = { | |||
| children: PropTypes.node, | |||
| numOfElements: PropTypes.number, | |||
| } | |||
| export default UserReviewsSkeleton | |||
| @@ -0,0 +1,57 @@ | |||
| import { Box } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| import selectedTheme from "../../../themes"; | |||
| export const UserReviewsSkeletonContainer = styled(Box)` | |||
| width: 100%; | |||
| ` | |||
| export const UserReviewsSkeletonItemsContainer = styled(Box)` | |||
| width: 100%; | |||
| padding: 36px; | |||
| ` | |||
| export const UserReviewsSkeletonLine = styled(Box)` | |||
| display: flex; | |||
| flex-direction: row; | |||
| & * { | |||
| background-color: ${selectedTheme.skeletonItemColor}; | |||
| } | |||
| ` | |||
| export const UserReviewsSkeletonCircle = styled(Box)` | |||
| width: 54px; | |||
| height: 54px; | |||
| border-radius: 100%; | |||
| ` | |||
| export const UserReviewsSkeletonLineOne = styled(Box)` | |||
| width: 78px; | |||
| height: 18px; | |||
| margin-top: 18px; | |||
| margin-left: 18px; | |||
| ` | |||
| export const UserReviewsSkeletonLineSecond = styled(Box)` | |||
| width: 200px; | |||
| height: 14px; | |||
| margin-top: 18px; | |||
| margin-left: 9px; | |||
| margin-bottom: 4px; | |||
| flex: 1; | |||
| ` | |||
| export const UserReviewsSkeletonSquare = styled(Box)` | |||
| width: 14px; | |||
| height: 14px; | |||
| margin-top: 18px; | |||
| ` | |||
| export const UserReviewsSkeletonLineThird = styled(Box)` | |||
| width: 91px; | |||
| height: 14px; | |||
| margin-left: 23px; | |||
| ` | |||
| export const UserReviewsSkeletonLineForth = styled(Box)` | |||
| width: 154px; | |||
| height: 14px; | |||
| margin-top: 20px; | |||
| margin-bottom: 4px; | |||
| ` | |||
| export const UserReviewsSkeletonLineFifth = styled(Box)` | |||
| width: 121px; | |||
| height: 14px; | |||
| ` | |||
| @@ -0,0 +1,3 @@ | |||
| export const PRIMARY_PURPLE_COLOR = `rgb(90, 57, 131)`; | |||
| export const PRIMARY_YELLOW_COLOR = `rgb(247, 178, 38)`; | |||
| export const PRIMARY_PURPLE_DISABLED = `rgb(75, 92, 100)`; | |||
| @@ -16,23 +16,17 @@ export const useQueryString = () => { | |||
| const [globalQueryString, setGlobalQueryString] = useState(""); | |||
| const [initial, setInitial] = useState(true); | |||
| const [loadedFromURL, setLoadedFromURL] = useState(false); | |||
| // const [isFetched, setIsFetched] = useState(false); | |||
| const dispatch = useDispatch(); | |||
| // const sorting = useSorting(); | |||
| useEffect(() => { | |||
| const queryStringLocal = history.location.search.substring(1); | |||
| setQueryString(convertQueryStringBackend(queryStringLocal)); | |||
| setGlobalQueryString(queryStringLocal); | |||
| console.log("initial bre") | |||
| }, []); | |||
| useEffect(() => { | |||
| console.log(globalQueryString); | |||
| console.log(history.location.search.substring(1)) | |||
| if (globalQueryString === history.location.search.substring(1)) | |||
| setLoadedFromURL(true); | |||
| // qo.delete("location") | |||
| }, [globalQueryString]); | |||
| useEffect(() => { | |||
| @@ -124,13 +118,9 @@ export const useQueryString = () => { | |||
| urlParams.delete(item.key); | |||
| } | |||
| // } | |||
| console.log("item.key: ", item.key); | |||
| console.log("item.value: ", item.value); | |||
| if (!item.value) return; | |||
| urlParams.append(item.key, item.value); | |||
| console.log("querytString: ", urlParams.toString()) | |||
| }); | |||
| console.log("postavlja se"); | |||
| setQueryString(urlParams.toString()); | |||
| return urlParams.toString(); | |||
| } | |||
| @@ -40,7 +40,6 @@ const useSorting = () => { | |||
| const setSelectedSortOption = (payload, shouldGoFirstPage = false) => { | |||
| dispatch(setFilteredSortOption(payload)); | |||
| console.log("konzola sort: ", payload) | |||
| let _des_date = null; | |||
| let _des_popular = null; | |||
| if (payload.value === sortOptions.NEW.value) { | |||
| @@ -66,7 +66,7 @@ export default { | |||
| forgotPasswordEmail: "Email", | |||
| useDifferentEmail: "Iskoristite drugačiju lozinku.", | |||
| wrongCredentials: "Pogrešan mail ili lozinka!", | |||
| headerTitle: "Ulogujte se" | |||
| headerTitle: "Ulogujte se", | |||
| }, | |||
| password: { | |||
| weak: "slaba", | |||
| @@ -141,8 +141,25 @@ export default { | |||
| placeholder: "Pretraži gradove...", | |||
| }, | |||
| }, | |||
| offer: { | |||
| title: "NASLOV", | |||
| productName: "Naziv proizvoda...", | |||
| productDescription: "OPIS PROIZVODA", | |||
| description: "Opis...", | |||
| location: "LOKACIJA", | |||
| choseLocation: "Izaberi lokaciju", | |||
| category: "KATEGORIJA", | |||
| choseCategory: "Izaberi kategoriju", | |||
| subcategory: "PODKATEGORIJA", | |||
| choseSubcategory: "Izaberi podkategoriju", | |||
| condition: "STANJE", | |||
| choseCondition: "Izaberi Stanje", | |||
| supportedImagesFormats: | |||
| "Podržani formati fotografija: <strong>.JPG</strong> | <strong>.JPEG</strong> | <strong>.PNG</strong>", | |||
| continue: "NASTAVI", | |||
| }, | |||
| apiErrors: { | |||
| somethingWentWrong: "Greska sa serverom!" | |||
| somethingWentWrong: "Greska sa serverom!", | |||
| }, | |||
| header: { | |||
| addOffer: "Dodaj proizvod", | |||
| @@ -152,6 +169,10 @@ export default { | |||
| myOffers: "Moje objave", | |||
| checkEverything: "POGLEDAJ SVE", | |||
| myMessages: "Moje poruke", | |||
| newOffers: "Najnovije ponude" | |||
| newOffers: "Najnovije ponude", | |||
| }, | |||
| reviews: { | |||
| title: "Ova kompanija još uvek nema ocenu.", | |||
| altTitle: "Budite prvi da je ocenite" | |||
| } | |||
| }; | |||
| @@ -1,6 +1,10 @@ | |||
| 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) => { | |||
| @@ -8,13 +12,12 @@ const ItemDetailsLayout = (props) => { | |||
| <ItemDetailsLayoutContainer> | |||
| {props.children} | |||
| <Grid container maxHeight="xl" spacing={2}> | |||
| <Content item xs={12} lg={9} xl={9.6} md={8} > | |||
| <Content item xs={12} lg={9} xl={9.6} md={12}> | |||
| {props.content} | |||
| </Content> | |||
| <RightCard item xs={0} lg={3} xl={2.4} md={4} > | |||
| <RightCard item xs={12} lg={3} xl={2.4} md={12}> | |||
| {props.rightCard} | |||
| </RightCard> | |||
| </Grid> | |||
| </ItemDetailsLayoutContainer> | |||
| ); | |||
| @@ -2,27 +2,32 @@ import { Container, Grid } from "@mui/material"; | |||
| import styled from "styled-components"; | |||
| export const ItemDetailsLayoutContainer = styled(Container)` | |||
| padding-left: 60px; | |||
| padding-right: 0; | |||
| margin: 0; | |||
| width: 100%; | |||
| max-width: none; | |||
| display: flex; | |||
| flex: 1; | |||
| height: 100%; | |||
| @media (max-width: 1024px) { | |||
| padding-right: 54px; | |||
| } | |||
| @media (max-width: 600px) { | |||
| padding-left: 18px; | |||
| padding-right: 18px; | |||
| } | |||
| ` | |||
| padding-left: 60px; | |||
| padding-right: 0; | |||
| margin: 0; | |||
| width: 100%; | |||
| max-width: none; | |||
| display: flex; | |||
| position: relative; | |||
| flex: 1; | |||
| height: 100%; | |||
| @media (max-width: 1024px) { | |||
| padding-right: 18px; | |||
| } | |||
| @media (max-width: 600px) { | |||
| padding-left: 18px; | |||
| padding-right: 18px; | |||
| } | |||
| `; | |||
| export const RightCard = styled(Grid)` | |||
| margin-top: 30px; | |||
| border-top-right-radius: 4px; | |||
| width: 100%; | |||
| ` | |||
| margin-top: 30px; | |||
| border-top-right-radius: 4px; | |||
| width: 100%; | |||
| /* @media (max-width: 800px) { | |||
| position: relative; | |||
| bottom: -500px; | |||
| } */ | |||
| `; | |||
| export const Content = styled(Grid)` | |||
| ` | |||
| `; | |||
| @@ -2,20 +2,14 @@ import React, { useEffect } from "react"; | |||
| import { PropTypes } from "prop-types"; | |||
| // import Navbar from "../../components/MUI/NavbarComponent"; | |||
| import { ItemDetailsPageContainer } from "./ItemDetailsPage.styled"; | |||
| import { useDispatch, useSelector } from "react-redux"; | |||
| import { useDispatch} 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 = (props) => { | |||
| const dispatch = useDispatch(); | |||
| const offer = useSelector(selectOffer); | |||
| const offerId = props.match.params.idProizvod; | |||
| @@ -25,19 +19,14 @@ const ItemDetailsPage = (props) => { | |||
| } | |||
| }, [offerId]); | |||
| useEffect(() => { | |||
| if (typeof offer !== 'undefined' && typeof offer.userId !== 'undefined' && offer.userId !== '') { | |||
| console.log(offer.userId); | |||
| } | |||
| }, [offer]) | |||
| return ( | |||
| <ItemDetailsPageContainer> | |||
| {/* <Navbar /> */} | |||
| {/* right card mora mi bude Review Card */} | |||
| <ItemDetailsLayout content={<ItemDetails />} rightCard={<UserReviewsCard />} /> | |||
| <ItemDetailsLayout | |||
| content={<ItemDetails />} | |||
| rightCard={<UserReviewsCard />} | |||
| /> | |||
| {/* <Box sx={{ mt: 4, mx: 4 }}> | |||
| <GridStyled container justifyContent="space-between"> | |||
| @@ -67,9 +56,9 @@ const ItemDetailsPage = (props) => { | |||
| ItemDetailsPage.propTypes = { | |||
| match: PropTypes.shape({ | |||
| params: PropTypes.shape({ | |||
| idProizvod:PropTypes.string | |||
| }) | |||
| }) | |||
| idProizvod: PropTypes.string, | |||
| }), | |||
| }), | |||
| }; | |||
| export default ItemDetailsPage; | |||
| @@ -10,19 +10,7 @@ import Profile from "../../components/Profile/Profile"; | |||
| const ProfilePage = () => { | |||
| return ( | |||
| <ProfilePageContainer> | |||
| {/* <Navbar /> */} | |||
| {/* <ProfilePageWrapper | |||
| container | |||
| direction="row" | |||
| justifyContent="center" | |||
| alignItems="start" | |||
| sx={{ pt: 3 }} | |||
| > | |||
| {/* <FilterCard /> | |||
| <ProfileCard /> | |||
| <UserReviewsCard heading="Moje ocene" /> | |||
| </ProfilePageWrapper> */} | |||
| <ItemDetailsLayout content={<Profile/>} rightCard={<UserReviewsCard/>} /> | |||
| <ItemDetailsLayout content={<Profile/>} rightCard={<UserReviewsCard profileReviews/>} /> | |||
| </ProfilePageContainer> | |||
| ); | |||
| }; | |||
| @@ -46,7 +46,7 @@ const Register = () => { | |||
| console.log(error); | |||
| const { mail, password, PIB, image } = informations; | |||
| if (error.type === "mail") { | |||
| setInformations({image}); | |||
| setInformations({ image }); | |||
| setCurrentStep(1); | |||
| setMailError(mail); | |||
| if ( | |||
| @@ -86,20 +86,19 @@ const Register = () => { | |||
| const setImage = (image) => { | |||
| setImageError(false); | |||
| setInformations(prevInfo => ({ | |||
| setInformations((prevInfo) => ({ | |||
| ...prevInfo, | |||
| image | |||
| })) | |||
| } | |||
| image, | |||
| })); | |||
| }; | |||
| const goStepBack = (stepNumber) => { | |||
| setCurrentStep(stepNumber); | |||
| const { mail, password, image } = informations; | |||
| if (stepNumber === 1) { | |||
| setInformations({image}); | |||
| setInformations({ image }); | |||
| } | |||
| if (stepNumber === 2) { | |||
| setInformations({ mail, password, image }); | |||
| } | |||
| }; | |||
| @@ -125,7 +124,7 @@ const Register = () => { | |||
| /> | |||
| </ProgressContainer> | |||
| <ProfileImagePicker setImage={setImage} > | |||
| <ProfileImagePicker setImage={setImage}> | |||
| <ProfilePicture /> | |||
| </ProfileImagePicker> | |||
| @@ -1,162 +1,162 @@ | |||
| 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', | |||
| getProfile: 'users/' | |||
| "/users?fp={fp}&offer={offer}&landingPageUrl={landingPageUrl}®istrationFlowType={registrationFlowType}", | |||
| updateUserRegistration: "/users/{userUid}", | |||
| invite: "/users/invite", | |||
| getProfile: "users/", | |||
| }, | |||
| 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: { | |||
| getOneOffer: 'offers', | |||
| @@ -14,7 +14,7 @@ const request = axios.create({ | |||
| export const getRequest = (url, params = null, options = null) => { | |||
| return request.get(url, { params, ...options }); | |||
| } | |||
| }; | |||
| export const postRequest = (url, data, params = null, options = null) => | |||
| request.post(url, data, { params, ...options }); | |||
| @@ -6,7 +6,6 @@ export const attemptFetchOffers = (payload) => { | |||
| return getRequest(apiEndpoints.offers.getOffers) | |||
| } | |||
| export const attemptFetchOneOffer = (payload) => { | |||
| // console.log(payload); | |||
| const url = `${apiEndpoints.offers.getOneOffer}/${payload.payload}/frontend`; | |||
| return getRequest(url); | |||
| } | |||
| @@ -32,7 +32,7 @@ export default ({ dispatch }) => | |||
| if (!response.headers?.Authorization) { | |||
| response.headers.Authorization = `Bearer ${jwtToken}`; | |||
| } | |||
| // If refresh token is expired, log out user | |||
| if (new Date() > new Date(refreshTokenDecoded?.exp * 1000)) { | |||
| dispatch(logoutUser()); | |||
| @@ -44,9 +44,10 @@ export default ({ dispatch }) => | |||
| token: refresh, | |||
| }); | |||
| const newToken = axiosResponse.data.token; | |||
| response.headers.Authorization = `Bearer ${newToken}` | |||
| dispatch(refreshUserToken(newToken)); | |||
| } | |||
| return Promise.resolve(response); | |||
| }, accessTokensMiddlewareInterceptorName); | |||
| @@ -88,10 +88,9 @@ function* fetchMoreOffers(payload) { | |||
| function* createOffer(payload) { | |||
| try { | |||
| const data = yield call(attemptAddOffer, payload); | |||
| const data = yield call(attemptAddOffer, payload.payload); | |||
| console.log(data); | |||
| } | |||
| catch (e) { | |||
| } catch (e) { | |||
| console.log(e); | |||
| } | |||
| } | |||
| @@ -22,5 +22,6 @@ export const primaryThemeColors = { | |||
| imagePickerBackground: "#E4E4E4", | |||
| iconYellowColor: "#FEB005", | |||
| iconMineProfileColor: "#9E9E9E", | |||
| iconProfileColor: "#C4C4C4" | |||
| } | |||
| iconProfileColor: "#C4C4C4", | |||
| skeletonItemColor: "#F4F4F4" | |||
| } | |||