Browse Source

Add sroll,fotos

DeJaVu 2 years ago
parent
commit
2ed0ce1403

+ 9 - 19
src/App.js

@@ -1,27 +1,18 @@
 import React from 'react';
 import './App.scss';
-import {Provider, connect}   from 'react-redux';
-import thunk from 'redux-thunk';
-import {createStore, combineReducers, applyMiddleware} from 'redux';
-import {Navibar} from './Components/NaviBar';
+import {Provider}   from 'react-redux';
 import Footer from './Components/Footer';
 import { createBrowserHistory } from "history";
-import { actionAuthLogout } from './actions';
-
 import store from './reducers';
 import ConnectLog from './pages/Login';
-
-import { Router,Switch, Route, Link, useHistory } from "react-router-dom";
-
-import TypeAd, {Home} from "./pages/Home";
+import { Router,Switch } from "react-router-dom";
+import TypeAd from "./pages/Home";
 import TypeAdOne from './pages/AdOne';
 import ConnectSign from './pages/Sign';
-import {Login} from "./pages/Login";
 import {Instruction} from "./pages/Instriction";
 import {Advertisment} from "./pages/Advertisment";
 import RoleRoute from './Components/PrivateRoute';
 import ConnectNav from './Components/NaviBar';
-import CProfile from './Components/Profile';
 import CPost from './pages/PostAd';
 import СChange from './pages/EditAd';
 import Profile from './pages/Profile';
@@ -34,12 +25,12 @@ function App() {
       <Router history = {createBrowserHistory()}>
           <ConnectNav />
           <Switch>
-            <RoleRoute exact path='/' roles ={['user']} component = {TypeAd}  />
-            <RoleRoute path='/home/:id' roles={['user']} component={TypeAdOne} exact/>
-            <RoleRoute path='/home/edit/:id' roles={['user']} component={СChange} exact/>
-            <RoleRoute path='/login' roles={['unknown']} component={ConnectLog}/>
-            <RoleRoute path='/sign' roles={['unknown']} component={ConnectSign}/>
-            <RoleRoute path='/search/' roles={['unknown']} component={AdSearch} />
+            <RoleRoute path='/' roles ={['user']} component = {TypeAd} exact />
+            <RoleRoute path='/home/:id' roles={['user']} component={TypeAdOne} exact />
+            <RoleRoute path='/home/edit/:id' roles={['user']} component={СChange} exact />
+            <RoleRoute path='/login' roles={['unknown']} component={ConnectLog} />
+            <RoleRoute path='/sign' roles={['unknown']} component={ConnectSign} />
+            <RoleRoute path='/search/:searchName' roles={['unknown']} component={AdSearch} />
             <RoleRoute path='/profile' roles={['user']} component={Profile} />
             <RoleRoute path='/post-ad' roles={['user']} component={CPost} />
             <RoleRoute path='/instruction' roles={['unknown']} component={Instruction} />
@@ -52,5 +43,4 @@ function App() {
   );
 }
 
-
 export default App;

+ 23 - 4
src/App.scss

@@ -165,10 +165,10 @@ html,body {
     overflow-x: hidden;
 
     img {
-        max-width: 200px;
-        min-width: 200px;
-        max-height: 300px;
-        min-height: 150px;
+        max-width: 250px;
+        min-width: 250px;
+        max-height: 250px;
+        min-height: 250px;
         padding-left: 0px;
         border: 0;
     }
@@ -212,6 +212,17 @@ html,body {
         flex-direction: column;
         justify-content: flex-start;
         border-radius: 15px;
+        b {
+            font-weight: 600;
+            font-size: 30px;
+        }
+        input {
+            width: 50%;
+            margin-bottom: 15px;
+        }
+        button {
+            width: 50%;
+        }
     }
 }
 
@@ -221,9 +232,17 @@ html,body {
     padding: 25px 15px;
     background-color: whitesmoke;
     border-radius: 15px;
+    .carousel {
+        margin: 0 auto;
+        width: 50%;
+        img {
+            height: 45vh
+        }
+    }
 }
 
 .profile {
+    margin-top: 25px;
     img {
         width: 20vh;
         height: 20vh;

+ 5 - 4
src/Components/AdOne.js

@@ -3,6 +3,7 @@ import { Container } from "react-bootstrap";
 import { Carousel } from 'react-responsive-carousel';
 import nofoto from '../images/placeholder.png'
 import "react-responsive-carousel/lib/styles/carousel.min.css";
+import CCommentInput from "./CommentInput";
 
 export const AdOne=({price, title,description,images,comments,createdAt,owner}) => {
     function timeConverter(t){
@@ -27,20 +28,20 @@ export const AdOne=({price, title,description,images,comments,createdAt,owner})
                     
                 </Carousel>
                 <div className='mainInfo'>
-                    <p>{`Опубликовано: ${timeConverter(createdAt)}`}</p>
+                    <i>{`Опубликовано: ${timeConverter(createdAt)}`}</i>
                     <b>{title}</b>
                     <h4>{`${price ? price : "0"} грн.`}</h4>
                     <p>{description}</p>
                     <p>{`Владелец: ${owner.login}`}</p>
-                    <p>{`На marketplace c: ${timeConverter(owner.createdAt)}`}</p>
+                    <p>{`Зарегистрирован на marketplace: ${timeConverter(owner.createdAt)}`}</p>
                 </div>
                 <div className='mainInfo'>
                     {comments ? 
                         comments.map(comment => {
-                            return (<div><p>{`Коментарии : ${comment.text}`}</p>
-                            <p>{`От: ${comment.owner.login}`}</p></div>)})
+                            return (<div><p>{` ${comment.owner.login} : ${comment.text}`}</p></div>)})
                             : <p>Коментариев нет</p>
                     }
+                <CCommentInput />
                 </div>
             </div>
         </Container>

+ 0 - 12
src/Components/CAdFeed.js

@@ -4,18 +4,6 @@ import { Container } from "react-bootstrap";
 import nofoto from '../images/placeholder.png'
 
 export const AdFeed=({_id, price,title,description,images,comments,createdAt}) => {
-    function timeConverter(t){
-        let a = new Date(+t);
-        let months = ['Января','Февраля','Марта','Апреля','Мая','Июня','Июля','Августа','Сентября','Октября','Ноября','Декабря'];
-        let year = a.getFullYear();
-        let month = months[a.getMonth()];
-        let date = a.getDate();
-        let hour = a.getHours();
-        let min = a.getMinutes();
-        let sec = a.getSeconds();
-        let time = date + ' ' + month + ' ' + year + ' в ' + hour + ':' + min ;
-        return time;
-      }
     return (
         <Container>
             <div className="row ad ">

+ 18 - 0
src/Components/CommentInput.js

@@ -0,0 +1,18 @@
+import { useState } from "react"
+import { connect } from "react-redux"
+import { actionAddComment } from "../actions"
+
+
+const CommentInput = ({onPost}) => {
+    const [comment,setComment] = useState('')
+    return (
+        <>  
+            <input type="text" value={comment} onChange={e => setComment(e.target.value)} placeholder="Ваш коментарий" />
+            <button onClick={()=> comment.length>0 && onPost(comment)}>Добавить коментарий</button>
+        </>
+    )
+}
+
+const CCommentInput = connect(null,{onPost: actionAddComment})(CommentInput)
+
+export default CCommentInput

+ 0 - 1
src/Components/DropZone.js

@@ -7,7 +7,6 @@ import {useDropzone} from 'react-dropzone'
 export function MyDropzone({onSend}) {
   const loading = useRef()  
     const {acceptedFiles, getRootProps, getInputProps} = useDropzone();
-    // const files = acceptedFiles.map(file => <li key={file.path}>{file.path}</li>);
     if(acceptedFiles.length > 0 && !loading.current) {
       onSend(acceptedFiles[0])
       loading.current = true

+ 3 - 5
src/Components/Footer.js

@@ -8,21 +8,19 @@ const Footer = () =>
         <div className="container text-center ">
             <div className="row">
                 <div className="col-md-6 mt-md-0 mt-3">
-                    <h5 className="text-uppercase">Что-то</h5>
-                    <p>будет</p>
+                <ul className="list-unstyled">
+                        <li><Link to="/instruction">Инструкция</Link></li>
+                    </ul>
                 </div>
 
                 <div className="col-md-6 mb-md-0 mb-3">
                     <ul className="list-unstyled">
-                        <li><Link to="/instruction">Инструкция</Link></li>
                         <li><Link to="/advertisment">Реклама</Link></li>
                     </ul>
                 </div>
             </div>
         </div>
-
         <div className="footer-copyright text-center py-3">© 2021 Copyright</div>
-
     </footer>
 </>
 

+ 1 - 12
src/Components/MyPosts.js

@@ -4,18 +4,7 @@ import { Container } from "react-bootstrap";
 import nofoto from '../images/placeholder.png'
 
 export const MyFeed=({_id, price, owner,title,description,images,comments,createdAt}) => {
-    function timeConverter(t){
-        let a = new Date(+t);
-        let months = ['Января','Февраля','Марта','Апреля','Мая','Июня','Июля','Августа','Сентября','Октября','Ноября','Декабря'];
-        let year = a.getFullYear();
-        let month = months[a.getMonth()];
-        let date = a.getDate();
-        let hour = a.getHours();
-        let min = a.getMinutes();
-        let sec = a.getSeconds();
-        let time = date + ' ' + month + ' ' + year + ' в ' + hour + ':' + min ;
-        return time;
-      }
+    
     return (
         <Container>
             <div className="row ad">

+ 4 - 6
src/Components/Profile.js

@@ -10,19 +10,17 @@ import unknown from '../images/unknown.jpg'
 const Profile = ({ userData, postsData, getPosts }) => {
     useEffect(() => getPosts(), [])
     return (
-        <CPromiseComponent promiseName='UserInfo'>
+        <CPromiseComponent promiseName='MyPosts'>
             <Container>
                 <div className='d-flex flex-column justify-content-center align-items-center profile'>
-                    <h4>{userData?.login}</h4>
                     <img src={userData?.avatar ? userData?.avatar.url : unknown} />
                     <CDrop />
+                    <h4>{userData?.login}</h4>
                 </div>
                 <div>
                     <h4>Ваши объявления:</h4>
-                    <CPromiseComponent promiseName='MyPosts'>
-                        {postsData && Object.keys(postsData).length == 0 && <h6>У вас еще нет обьявлений</h6>}
-                        {postsData?.map(ad => <MyFeed key={ad._id} _id = {ad. _id} price = {ad.price} title = {ad.title} description={ad.description} owner={ad.owner} images={ad.images} comments={ad.comments} />) }
-                    </CPromiseComponent>
+                    {postsData && Object.keys(postsData).length == 0 && <h6>У вас еще нет обьявлений</h6>}
+                    {postsData?.map(ad => <MyFeed key={ad._id} _id = {ad. _id} price = {ad.price} title = {ad.title} description={ad.description} owner={ad.owner} images={ad.images} comments={ad.comments} />) }
                 </div>
             </Container>
         </CPromiseComponent>

+ 15 - 0
src/Components/RegErrors/SearchError.js

@@ -0,0 +1,15 @@
+import { Container } from "react-bootstrap";
+import badsearch from '../../images/badsearch.png'
+
+const ErrorSearch = ({}) => {
+    return (
+        <Container>
+            <div className='d-flex justify-content-center  m-5'>
+                <h2>Данного товара не существует,попробуйте другой запрос</h2>
+                {/* <img style={{width: '25%'}} src={badsearch}/> */}
+            </div>
+        </Container>
+    )
+}
+
+export default ErrorSearch

+ 3 - 4
src/Components/Search.js

@@ -1,15 +1,14 @@
 import { useState } from "react"
 import { Link } from "react-router-dom"
-import { actionSearch } from "../actions"
 import loop from '../images/search.svg'
 
 const Search = ({}) => {
-    const [search,setSearch] = useState('')
+    const [searchName,setsearchName] = useState('')
     return (
         <div class="d1">
             <form>
-                <input type="text" value={search} onChange={e => setSearch(e.target.value)} placeholder="Искать здесь" />
-                <Link to='/search/' className='search'><img src={loop} /></Link>
+                <input type="text" value={searchName} onChange={e => setsearchName(e.target.value)} placeholder="Искать здесь" />
+                <Link to={`/search/${searchName}`} className='search'><img src={loop} /></Link>
             </form>
         </div>
     )

+ 65 - 58
src/actions/index.js

@@ -75,8 +75,10 @@ export const actionFullRegister = (login,password) =>
     }
   }
 
-export const actionTypeAd = (_id,title) =>
-    actionPromise('AdFind', shopGQL(`
+export const actionTypeAd = (title, skip = 0) =>
+async(dispatch,getState) => {
+    let ads = getState().promiseReducer.AdFind?.payload?.data.AdFind
+    await dispatch(actionPromise('AdFind', shopGQL(`
             query Ad($query:String){
               AdFind(query:$query){
                 _id  
@@ -93,7 +95,13 @@ export const actionTypeAd = (_id,title) =>
                 owner {login}
               }
             }
-        `, {query: JSON.stringify([{field: title},{sort: [{_id: -1}]}])}))
+        `, {query: JSON.stringify([{field: title},{sort: [{_id: -1}],skip : [skip], limit: [50]}])}
+        )))
+        if(ads) {
+          ads.concat(skip)
+        }
+      }
+      
 
 export const actionTypeAdOne = (id) => 
           actionPromise('AdFindOne',shopGQL(`
@@ -127,19 +135,47 @@ export const actionTypeAdOne = (id) =>
 //               }
 //             }`,{query: JSON.stringify([{}])}))
 
-export const actionPostAd = (title,description,price,_id) =>
-            actionPromise('PostAd',shopGQL(`
-            mutation Post($ad: AdInput){
-              AdUpsert(ad: $ad) {
-                  _id
-                  title
-                  description
-                  price
-                  images {
-                    url
+export const actionAddComment = (text) => 
+async(dispatch,getState) => {
+  let adId = getState().promiseReducer.AdFindOne.payload.data.AdFindOne._id
+  let addedCom = await dispatch(actionPromise('AddComment',shopGQL(`
+  mutation Comment($comment: CommentInput){
+    CommentUpsert(comment: $comment){
+      _id
+      text
+      owner {login}
+      ad {_id}
+    }
+  }`,{comment: {text,ad: {_id: adId}}})))
+  if(addedCom) {
+    dispatch(actionTypeAdOne(adId))
+  }
+}
+
+
+export const actionPostAd = (title,description,price,files,_id) =>
+            async dispatch => {
+              let res = await dispatch(actionUploadFiles(files))
+              let imagesId = res.map(({_id}) => ({_id}))
+              if(res){
+                let upsert = actionPromise('PostAd',shopGQL(`
+                mutation Post($ad: AdInput){
+                  AdUpsert(ad: $ad) {
+                      _id
+                      title
+                      description
+                      price
+                      images {
+                        url
+                      }
+                    }
+                  }`,{ad: {title,description,price,images: imagesId,_id}}))
+                  if(upsert) {
+                    await dispatch(actionTypeAd())
+                    await dispatch(actionMyPosts())
                   }
-                }
-              }`,{ad: {title,description,price,_id}}))
+              }
+            }
 
 export const actionMyPosts = () =>
     async (dispatch,getState) => {
@@ -155,31 +191,29 @@ export const actionMyPosts = () =>
               url
             }
             comments {
-              _id text owner {login} answerTo { owner { login}}
+              _id text owner {login} answerTo { owner { login}} ad {_id}
             }
           }
-        }`,{query: JSON.stringify([{___owner: userId}])})))
+        }`,{query: JSON.stringify([{___owner: userId},{sort: [{_id: -1}]}])})))
       }
-    
-// export const actionCommentAdd = () =>
-//               actionPromise('CommentAdd',shopGQL(`
-//               mutation Comment($comment : CommentInput){
-//                 CommentUpsert(comment: $comment) {
-//                   _id
-//                   ad
-//                   text
-//                 }
-//               }`,{comment:{text,answerTo,ad:{_id}}}))
+
 
 export const actionUploadFile = (file) => {
+  return actionPromise('photo',fetchFiles(file))
+};
+
+const fetchFiles = (file) => {  
   let fd = new FormData
   fd.append('photo', file)
-  return actionPromise('photo',fetch('/upload', {
+  return fetch('/upload', {
     method: "POST",
     headers: localStorage.authToken ? {Authorization: 'Bearer ' + localStorage.authToken} : {},
     body: fd
-  }).then(res => res.json()))
-};
+  }).then(res => res.json())
+}
+
+export const actionUploadFiles = (files) => 
+  actionPromise('photos',Promise.all(files.map(file => fetchFiles(file))))
 
 const actionAvaAdd = (avaId) => 
 async (dispatch,getState) => {
@@ -214,7 +248,7 @@ export const actionUserInfo = () =>
   }
 
 
-const regexp = (string) => `/${string.split([" "]).join(['|']).trim()}/`
+const regexp = (string) => `/${string.split(" ").join('|').trim()}/`
 const toQuery = (queryString, fields = ["title", "description"]) => ({ $or: fields.map(string => ({ [string]: regexp(queryString) }))})
 export const actionSearch = (queryString) => 
 async (dispatch) =>
@@ -238,30 +272,3 @@ async (dispatch) =>
   )
 ))
 
-// const toRegexp2 = queryString => `/${queryString.split([" "]).join(['|']).trim()}/`
-// const toQuery = (queryString, fields = ["id3.artist", "id3.title", "id3.album"]) => ({ $or: fields.map(x => ({ [x]: toRegexp2(queryString) })) })
-
-// const actionSearch = (queryString) =>
-//     async dispatch => {
-//         let searchData = await dispatch(actionPromise('search', gql(
-//             `query trackFind($query: String) {
-//             TrackFind(query:$query)
-//               {
-//                   originalFileName
-//                   url
-//                   id3 {
-//                           title
-//                           artist
-//                           album
-//                       }
-//               }
-//           }`, {
-//             query: JSON.stringify([toQuery(queryString),
-//             {
-//                 sort: [{ _id: -1 }], //сортировка в обратном хронологическом порядке
-//                 limit: [10],  //100 записей максимум
-//             }])
-//         }
-//         )))
-//         console.log(searchData)
-//     }

BIN
src/images/badsearch.png


+ 44 - 6
src/pages/EditAd.js

@@ -1,20 +1,41 @@
-import React ,{useState,useEffect} from "react";
+import React ,{useState,useEffect,useRef} from "react";
 import { connect } from "react-redux";
 import { actionPostAd, actionTypeAdOne } from "../actions";
 import { Container } from "react-bootstrap";
 import CPromiseComponent from "../Components/PromiseComponent";
-import { Redirect } from "react-router";
+import { Redirect , useHistory} from "react-router";
+import {useDropzone} from 'react-dropzone'
+import { Carousel } from 'react-responsive-carousel';
+import nofoto from '../images/placeholder.png'
+import "react-responsive-carousel/lib/styles/carousel.min.css";
 
 
-const Post = ({data,onChange,match:{params:{id}},getData, posted}) => {
+const Post = ({data,onChange,match:{params:{id}},getData}) => {
+    let history = useHistory()
+
     let [title,setTitle] = useState('')
     let [description,setDescription] = useState('')
     let [price,setPrice] = useState(0)
+    let [images,setImages] = useState()
+
+    const loading = useRef()  
+    const {acceptedFiles, getRootProps, getInputProps} = useDropzone();
+    // const files = acceptedFiles.map(file => <li key={file.path}>{file.path}</li>);
+    if(acceptedFiles.length > 0 && !loading.current) {
+      loading.current = true
+    }
+
+    const files = acceptedFiles.map(file => (
+        <li key={file.name}>
+          {file.name}
+        </li>
+      ));
 
     useEffect(()=>{
         setTitle(data?.title)
         setDescription(data?.description)
         setPrice(data?.price)
+        setImages(data?.images)
     },[data])
 
     useEffect(() => 
@@ -29,6 +50,24 @@ const Post = ({data,onChange,match:{params:{id}},getData, posted}) => {
                         <label>Введите название</label>
                         <input value={title} onChange={e => setTitle(e.target.value)} ></input>
                     </div>
+                    <div className='post'>
+                        <Carousel className='carousel' infiniteLoop useKeyboardArrows showStatus={false} showThumbs={false} >
+                            {images ? images.map(image =>  
+                                <img src = {`http://marketplace.asmer.fs.a-level.com.ua/${image.url}`} />
+                            ): <img src={nofoto} />} 
+                        </Carousel>
+                    </div>
+                    <div className='post'>
+                        <div {...getRootProps({className: 'dropzone'})}>
+                            <input onChange={e => setImages(e.target.value)} {...getInputProps() }/>
+                            <p>Фото, нажмите для обновления</p>
+                            <label>Первое фото будет на обложке объявления</label>
+                        </div>
+                        <aside>
+                            <h5>Фото: </h5>
+                            <ul>{files}</ul>
+                        </aside>
+                    </div>
                     <div className='d-flex flex-column align-items-start post'>
                         <label>Описание</label>
                         <textarea rows="5" cols="75" value={description} onChange={e => setDescription(e.target.value)} ></textarea>
@@ -38,14 +77,13 @@ const Post = ({data,onChange,match:{params:{id}},getData, posted}) => {
                         <input type={"number"} value={price} onChange={e => e.target.value>=0 ? setPrice(+e.target.value) : ""} ></input>
                     </div>
                     <div className="d-flex flex-column align-items-end post">
-                        <button onClick={()=> onChange(title,description,price,data._id)}>Изменить объявление</button>
+                        <button onClick={()=> onChange(title,description,price,data.images && acceptedFiles,data._id) && history.push('/profile')}>Изменить объявление</button>
                     </div>
                 </Container>
             </CPromiseComponent>
-            {posted && <Redirect push to ='/profile'/>} 
         </>
     )
 }
 
-const CChange = connect(state => ({data: state.promiseReducer.AdFindOne?.payload?.data?.AdFindOne, posted: state.promiseReducer.PostAd?.payload?.data?.AdUpsert}),{onChange: actionPostAd, getData: actionTypeAdOne})(Post)
+const CChange = connect(state => ({data: state.promiseReducer.AdFindOne?.payload?.data?.AdFindOne}),{onChange: actionPostAd, getData: actionTypeAdOne})(Post)
 export default CChange

+ 23 - 8
src/pages/Home.js

@@ -1,15 +1,30 @@
-import React, {useEffect} from "react";
+import React, {useEffect, useState} from "react";
 import {connect}   from 'react-redux';
 import {AdFeed} from "../Components/CAdFeed";
-import {AdOne} from "../Components/AdOne";
-import { actionTypeAd ,actionTypeAdOne} from "../actions";
-import { Redirect } from "react-router";
-import {useHistory} from 'react-router-dom';
-import Loader from "../Components/PreLoader";
-import { CAdfeed } from "../Components/CAdFeed";
+import { actionTypeAd} from "../actions";
 import CPromiseComponent from "../Components/PromiseComponent";
+
 export const Home = ({getData,data}) => {
-    useEffect(()=>getData(),[])
+    const [fetching,setFetching] = useState(true)
+    const [current,setCurrent] = useState(0)
+    useEffect(()=>{
+        if(fetching){
+            getData()
+        }},[fetching])
+
+    useEffect(() => {
+        document.addEventListener('scroll',scrollHandler)
+        return function() {
+            document.removeEventListener('scroll',scrollHandler)
+        }
+    },[])
+
+    const scrollHandler = (e) => {
+        if(e.target.documentElement.scrollHeight - (window.innerHeight + e.target.documentElement.scrollTop)< 100){
+           setFetching(true)
+           console.log(e.target.documentElement.scrollHeight)
+        }
+    }
     if(data){
         return (
             <CPromiseComponent promiseName='AdFind'>

+ 1 - 4
src/pages/Login.js

@@ -7,10 +7,7 @@ import LoginError from "../Components/RegErrors/LoginError";
 import showPwdImg from '../images/3844476-eye-see-show-view-watch_110339.svg';
 import hidePwdImg from '../images/3844477-disable-eye-inactive-see-show-view-watch_110343.svg';
 import {Link, useHistory} from 'react-router-dom';
-import { authReducer } from "../reducers/authReducer";
-import { Redirect } from "react-router";
-import { Nav } from "react-bootstrap";
-import CPromiseComponent from "../Components/PromiseComponent";
+
 
 const LoginForm = ({onLogin,loggedIn}) => {
   const [login,setLogin] = useState('')

+ 28 - 2
src/pages/PostAd.js

@@ -1,19 +1,45 @@
-import React ,{useState} from "react";
+import React ,{useState, useRef} from "react";
 import { connect } from "react-redux";
 import { actionPostAd } from "../actions";
 import { Container } from "react-bootstrap";
+import {useDropzone} from 'react-dropzone'
+import { Redirect ,useHistory} from "react-router";
 
 
 const Post = ({onPost}) => {
+    let history = useHistory()
     let [title,setTitle] = useState('')
     let [description,setDescription] = useState('')
     let [price,setPrice] = useState(0)
+    const loading = useRef()  
+    const {acceptedFiles, getRootProps, getInputProps} = useDropzone();
+    if(acceptedFiles.length > 0 && !loading.current) {
+      loading.current = true
+    }
+
+    const files = acceptedFiles.map(file => (
+        <li key={file.name}>
+          {file.name}
+        </li>
+    ));
+
     return (
         <Container >
             <div className='d-flex flex-column align-items-start post'>
                 <label>Введите название</label>
                 <input value={title} onChange={e => setTitle(e.target.value)} placeholder='Например,Iphone 8'></input>
             </div>
+            <div className='post'>
+                <div {...getRootProps({className: 'dropzone'})}>
+                  <input {...getInputProps() }/>
+                  <p>Фото, нажмите для добавления</p>
+                  <label>Первое фото будет на обложке объявления</label>
+                </div>
+                <aside>
+                    <h5>Фото: </h5>
+                    <ul>{files}</ul>
+                </aside>
+            </div>
             <div className='d-flex flex-column align-items-start post'>
                 <label>Описание</label>
                 <textarea rows="5" cols="75" value={description} onChange={e => setDescription(e.target.value)} placeholder='Подумайте,какие подробности вы бы хотели узнать из объявления. И добавьте их в описание'></textarea>
@@ -23,7 +49,7 @@ const Post = ({onPost}) => {
                 <input type={"number"} value={price} onChange={e => e.target.value>=0 ? setPrice(+e.target.value) : ""} placeholder='Цена' ></input>
             </div>
             <div className="d-flex flex-column align-items-end post">
-                <button onClick={()=> onPost(title,description,price)}>Опубликовать</button>
+                <button onClick={()=> onPost(title,description,price,acceptedFiles) && history.push('/')}>Опубликовать</button>
             </div>
         </Container>
     )

+ 5 - 6
src/pages/Search.js

@@ -3,14 +3,13 @@ import {connect}   from 'react-redux';
 import {AdFeed} from "../Components/CAdFeed";
 import { actionSearch} from "../actions";
 import CPromiseComponent from "../Components/PromiseComponent";
-export const Search = ({getData,data}) => {
-    useEffect(()=>getData(),[])
-    
+import ErrorSearch from "../Components/RegErrors/SearchError";
+export const Search = ({getData,data,match:{params:{searchName}}}) => {
+    useEffect(()=>getData(searchName),[searchName])
         return (
             <CPromiseComponent promiseName='SearchAd'>
-                <div>
-                    {data?.map(ad => <AdFeed key={ad._id} _id = {ad. _id} price = {ad.price} title = {ad.title} description={ad.description} images={ad.images} />)}
-                </div>
+                {data && Object.keys(data).length === 0 && <ErrorSearch />}
+                {data?.map(ad => <AdFeed key={ad._id} _id = {ad. _id} price = {ad.price} title = {ad.title} description={ad.description} images={ad.images}/>)}
             </CPromiseComponent>
         )