Browse Source

Add fixed

DeJaVu 2 years ago
parent
commit
b39465509b

+ 13 - 3
src/App.scss

@@ -59,6 +59,16 @@ html,body {
         display: flex;
         flex-direction: column;
         position: relative;
+
+        a {
+            text-decoration: none;
+            color:black;
+            font-size: 18px;
+        }
+        a:hover {
+            background-color: #002f34;
+            color: white;
+        }
     }
     .pwd-container {
         display: flex;
@@ -149,16 +159,16 @@ html,body {
 
 .profile {
     img {
-        width: 10%;
+        width: 20vh;
         height: 20vh;
-        border-radius: 100%;
+        border-radius: 50%;
     }
 }
 
 .loader {
     position: absolute;
     top: 40%;
-    left: 50%;
+    left: calc(50% - 80px);
     display: flex;
     justify-content: center;
     align-items: center;

+ 12 - 8
src/Components/AdOne.js

@@ -1,13 +1,17 @@
 import React from "react"; 
-import { Container } from "react-bootstrap";
+import { Container,Carousel } from "react-bootstrap";
 
-export const AdOne=({_id, price, title,description,images}) => {
+export const AdOne=({price, title,description,images}) => {
     return (
-        <div>
-            <img src = {`http://marketplace.asmer.fs.a-level.com.ua/${images ? images[0]?.url : ''}`} />
-            <p>{title}</p>
-            <p>{description}</p>
-            <p>{`${price ? price : "0"} грн.`}</p>
-        </div>
+        <Container>
+            <div>
+                <Carousel>
+                    <img src = {`http://marketplace.asmer.fs.a-level.com.ua/${images ? images[0]?.url : ''}`} />
+                </Carousel>
+                <p>{title}</p>
+                <p>{description}</p>
+                <p>{`${price ? price : "0"} грн.`}</p>
+            </div>
+            </Container>
     )
 }

+ 31 - 20
src/Components/CAdFeed.js

@@ -1,30 +1,41 @@
 import React from "react";
-import { actionTypeAd } from "../actions";
-import {connect} from 'react-redux';
 import {Link} from 'react-router-dom';
 import { Container } from "react-bootstrap";
+import nofoto from '../images/placeholder.png'
 
-export const AdFeed=({_id, price, owner,title,description,images,comments}) => {
+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">
-            <div className="col img">
-                <img src = {`http://marketplace.asmer.fs.a-level.com.ua/${images ? images[0]?.url : ''}`} />
-            </div> 
-            <div className="col-6" info>   
-                <Link to={ `/home/${_id}`}>{title}</Link>
-                <p>{description}</p>
+            <div className="row ad">
+                <div className="col img">
+                    <img src = {`http://marketplace.asmer.fs.a-level.com.ua/${images ? images[0]?.url : nofoto}`} />
+                </div> 
+                <div className="col-6" info>   
+                    <Link to={ `/home/${_id}`}>{title}</Link>
+                    <p>{description}</p>
+                </div>
+                <div className="col price">   
+                    <p>{`Цена: ${price ? price : "0"} грн.`}</p>
+                    <p>{`Добавлено: ${timeConverter(createdAt)}`}</p>
+                </div> 
+                <div>
+                    <p>{`Коментарии : ${comments ? comments[0]?.text : 'отсутвуют'}`}</p>
+                    <p>{`От : ${comments ? comments[0].owner.login : '-'}`}</p>
+                </div>   
             </div>
-            <div className="col price">   
-                <p>{owner}</p>
-                <p>{`${price ? price : "0"} грн.`}</p>
-            </div> 
-            <div>
-                <p>{`Коментарии : ${comments ? comments[0]?.text : 'отсутвуют'}`}</p>
-                <p>{`От : ${comments ? comments[0].owner.login : '-'}`}</p>
-            </div>   
-        </div>
         </Container> 
     )
 }
-// export const CAdfeed = connect(state=>({comments: state.promiseReducer.AdFind?.payload?.data?.AdFind.comments[0]?.owner}))(AdFeed)
+

+ 40 - 0
src/Components/MyPosts.js

@@ -0,0 +1,40 @@
+import React from "react";
+import {Link} from 'react-router-dom';
+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">
+                <div className="col img">
+                    <img src = {`http://marketplace.asmer.fs.a-level.com.ua/${images ? images[0]?.url : nofoto}`} />
+                </div> 
+                <div className="col-6" info>   
+                    <Link to={ `/home/${_id}`}>{title}</Link>
+                    <p>{description}</p>
+                </div>
+                <div className="col price">   
+                    <p>{owner}</p>
+                    <p>{`${price ? price : "0"} грн.`}</p>
+                </div> 
+                <div>
+                    <p>{`Коментарии : ${comments ? comments[0]?.text : 'отсутвуют'}`}</p>
+                    <p>{`От : ${comments ? comments[0].owner.login : '-'}`}</p>
+                </div>   
+            </div>
+        </Container> 
+    )
+}

+ 22 - 11
src/Components/Profile.js

@@ -1,20 +1,31 @@
-import React from "react";
+import React, { useEffect } from "react";
 import { Container } from "react-bootstrap";
 import { connect } from "react-redux";
+import { actionMyPosts } from "../actions";
 import CDrop from "./DropZone";
+import CPromiseComponent from "./PromiseComponent";
+import { MyFeed } from "./MyPosts";
+import unknown from '../images/unknown.jpg'
 
-const Profile = ({login,avatar,posts}) => {
+const Profile = ({ userData, postsData, getPosts }) => {
+    useEffect(() => getPosts(), [])
     return (
-        <Container>
-            <div className='d-flex flex-column justify-content-center align-items-center profile'>
-                <p>{login}</p>
-                <img src={avatar} alt='avatar' />
-                {console.log(avatar)}
-                <CDrop />
-            </div>
-        </Container>
+        <CPromiseComponent promiseName='UserInfo'>
+            <Container>
+                <div className='d-flex flex-column justify-content-center align-items-center profile'>
+                    <p>{userData?.login}</p>
+                    <img src={userData?.avatar ? userData?.avatar.url : unknown} />
+                    <CDrop />
+                </div>
+                <div>
+                    <h4>Ваши объявления:</h4>
+                    {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>
     )
 }
 
-const CProfile = connect(state => ({login: state.authReducer.payload.sub.login, avatar: state.promiseReducer?.photo?.payload?.url}))(Profile)
+const CProfile = connect(state => ({ userData: state.promiseReducer.UserInfo?.payload?.data?.UserFindOne , postsData: state.promiseReducer.MyPosts?.payload?.data?.AdFind }),{getPosts: actionMyPosts})(Profile)
 export default CProfile

+ 1 - 2
src/Components/PromiseComponent.js

@@ -1,6 +1,5 @@
-import React, { useState } from "react";
+import React from "react";
 import { connect } from "react-redux";
-import TypeAd from "../pages/Home";
 import Loader from "./PreLoader";
 
 const PromiseComponent = ({promiseStatus,promiseName,children}) => {

+ 48 - 25
src/actions/index.js

@@ -50,9 +50,13 @@ const actionLogin = (login, password) => actionPromise("login", log(login, passw
 export const actionFullLogin = (login, password) => {
   return async (dispatch) => {
       let result = await dispatch(actionLogin(login, password))
-      if(result)
+      if(result) {
           dispatch(actionAuthLogin(result))
-          // window.location.reload();
+          dispatch(actionUserInfo())
+      }
+      else {
+        console.log('undefined user')
+      }
   }
 }
 
@@ -63,23 +67,11 @@ const actionRegister = (login,password) =>
     }
 }`,{login,password}))
 
-
-// const actionAvaAdd = (ava,user) =>
-// actionPromise('ava',shopGQL(`mutation setAvatar{
-//   UserUpsert(user:{_id: "myid", avatar: {_id: "image id from fetch"}}){
-//       _id, avatar{
-//           _id
-//       }
-//   }
-// }`,{ava,user}))
-
-
 export const actionFullRegister = (login,password) => 
   async dispatch => {
     let payload = await dispatch(actionRegister(login,password))
     if(payload.data.createUser != null){
       await dispatch(actionFullLogin(login,password))
-      // await dispatch(actionAvaAdd(avatar,_id))
     }
     else {
       console.log("exiciting user")
@@ -100,6 +92,8 @@ export const actionTypeAd = (_id,title) =>
                 comments {
                   _id text owner {login} answerTo { owner { login}}
                 }
+                createdAt
+                owner {login}
               }
             }
         `, {query: JSON.stringify([{field: title},{sort: [{_id: -1}]}])}))
@@ -133,17 +127,34 @@ export const actionPostAd = (title,description,price) =>
               }`,{ad: {title,description,price}}))
 
 export const actionMyPosts = () =>
-              actionPromise('MyPosts',shopGQL(``))
-
-export const actionCommentAdd = () =>
-              actionPromise('CommentAdd',shopGQL(`
-              mutation Comment($comment : CommentInput){
-                CommentUpsert(comment: $comment) {
-                  _id
-                  ad
-                  text
-                }
-              }`,{comment:{text,answerTo,ad:{_id}}}))
+    async (dispatch,getState) => {
+      let userId = getState().authReducer.payload.sub.id
+      return await dispatch(actionPromise('MyPosts',shopGQL(`
+        query MyPosts($query: String){
+          AdFind(query: $query){
+            _id  
+            title
+            description
+            price
+            images {
+              url
+            }
+            comments {
+              _id text owner {login} answerTo { owner { login}}
+            }
+          }
+        }`,{query: JSON.stringify([{___owner: userId}])})))
+      }
+    
+// 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) => {
   let fd = new FormData
@@ -172,6 +183,18 @@ export const actionAvaChange = (file) =>
    let res =  await dispatch(actionUploadFile(file))
    if(res) {
      await dispatch(actionAvaAdd(res._id))
+     await dispatch(actionUserInfo())
    }
   }
+
+export const actionUserInfo = () => 
+  async (dispatch,getState) => {
+    let userId = getState().authReducer.payload.sub.id
+    await dispatch(actionPromise('UserInfo',shopGQL(`
+      query UserInfo($query:String){
+        UserFindOne(query: $query){
+          _id login avatar {url}
+        }
+      }`,{query: JSON.stringify([{_id: userId}])})))
+  }
   

BIN
src/images/placeholder.png


BIN
src/images/unknown.jpg


+ 5 - 5
src/pages/AdOne.js

@@ -5,19 +5,19 @@ import {actionTypeAdOne} from "../actions";
 import {useHistory} from 'react-router-dom';
 import CPromiseComponent from "../Components/PromiseComponent";
 
-export const Ad = ({getData3,data3, match:{params:{id}}}) => {
-    useEffect(()=>getData3(id),[id])
+export const Ad = ({getData,data, match:{params:{id}}}) => {
+    useEffect(()=>getData(id),[id])
 
-    if(data3){
+    if(data){
         return (
             <CPromiseComponent promiseName='AdFindOne'>
                 <div className="adone">
-                    <AdOne key={data3._id} price = {data3.price} title = {data3.title} description={data3.description}  images={data3.images} />
+                    <AdOne key={data._id} price = {data.price} title = {data.title} description={data.description}  images={data.images} />
                 </div>
             </CPromiseComponent>
         )
     }
 }
 
-const TypeAdOne = connect((state) => ({data3: state.promiseReducer.AdFindOne?.payload?.data?.AdFindOne || []}),{getData3: actionTypeAdOne})(Ad)
+const TypeAdOne = connect((state) => ({data: state.promiseReducer.AdFindOne?.payload?.data?.AdFindOne || []}),{getData: actionTypeAdOne})(Ad)
 export default TypeAdOne

+ 4 - 5
src/pages/Home.js

@@ -8,19 +8,18 @@ import {useHistory} from 'react-router-dom';
 import Loader from "../Components/PreLoader";
 import { CAdfeed } from "../Components/CAdFeed";
 import CPromiseComponent from "../Components/PromiseComponent";
-export const Home = ({getData,data2}) => {
+export const Home = ({getData,data}) => {
     useEffect(()=>getData(),[])
-   
-    if(data2){
+    if(data){
         return (
             <CPromiseComponent promiseName='AdFind'>
                 <div>
-                    {data2.map(ad => <AdFeed key={ad._id} _id = {ad. _id} price = {ad.price} title = {ad.title} description={ad.description} owner={ad.owner} images={ad.images} comments={ad.comments} />)}
+                    {data.map(ad => <AdFeed key={ad._id} _id = {ad. _id} price = {ad.price} title = {ad.title} description={ad.description} owner={ad.owner} images={ad.images} comments={ad.comments} createdAt={ad.createdAt} />)}
                 </div>
             </CPromiseComponent>
         )
     }
 }
 
-const TypeAd = connect(state => ({data2: state.promiseReducer.AdFind?.payload?.data?.AdFind || []}),{getData: actionTypeAd})(Home)
+const TypeAd = connect(state => ({data: state.promiseReducer.AdFind?.payload?.data?.AdFind || []}),{getData: actionTypeAd})(Home)
 export default TypeAd

+ 1 - 1
src/pages/Login.js

@@ -53,7 +53,7 @@ const loginCallback = () => {
                 <img src={open ? hidePwdImg : showPwdImg} onClick={() => setOpen(!open)}/>
             </div>
             <div className='login-container'>
-                <Link to='sign'>Зарегистрироваться</Link>
+                Не зарегистрированы? <Link to='sign' className='mb-3'>Создать аккаунт</Link>
                 <Button name='Войти' isValid={isLoginValid()} callback={loginCallback} /> 
             </div> 
                 {show && (!login || !password) && <LoginError />}

+ 1 - 2
src/pages/Sign.js

@@ -59,12 +59,11 @@ const Sign = ({onSign,loggedIn}) => {
               <input value={password} type={open ? "text" : "password"} onChange={e => setPassword(e.target.value)}  placeholder="Пароль"  />
               <img src={open ? hidePwdImg : showPwdImg} onClick={() => setOpen(!open)}/>
           </div>
-          <div className='pwd-container2'>
+          <div className='pwd-container2 mb-3'>
               <label>Повторите пароль</label>
               <input value={password2} type={open2 ? "text" : "password"} onChange={e => setPassword2(e.target.value)}  placeholder="Пароль"  />
               <img src={open2 ? hidePwdImg : showPwdImg} onClick={() => setOpen2(!open2)}/>
           </div>
-          <MyDropzone />
           <Button
                 name='Зарегистрироваться'
                 isValid={isRegistrationValid()}

+ 6 - 1
src/reducers/index.js

@@ -2,10 +2,15 @@ import thunk from 'redux-thunk';
 import {createStore, combineReducers, applyMiddleware} from 'redux';
 import { authReducer } from './authReducer';
 import { promiseReducer } from './promiseReducer';
+import { actionUserInfo } from '../actions';
 
 const rootReducer = combineReducers({
     promiseReducer,authReducer
 })
 const store = createStore(rootReducer, applyMiddleware(thunk)) 
+if(localStorage.authToken){
+    store.dispatch(actionUserInfo())
+}
 store.subscribe(()=> console.log(store.getState()))
-export default store
+
+export default store