Jelajahi Sumber

Add folders for pages and components in code

LenDoc 2 tahun lalu
induk
melakukan
5b3201a6f2

+ 3 - 65
src/App.js

@@ -1,82 +1,20 @@
 import './App.scss'
 import { Provider, connect } from 'react-redux'
 import { Router, Route, Redirect, Switch } from 'react-router-dom'
-import createHistory from 'history/createBrowserHistory'
 import React from 'react'
 import { store } from './redux/reducers'
-import { CPageAboutUser } from './components/User'
-import { CPost } from './components/Post'
 import 'antd/dist/antd.css'
 import { actionFullProfilePage } from './redux/thunk'
 import { actionFullAllGetPosts } from './actions'
-import { CExplorePosts } from './components/Explore'
-import { CPostForFeed, Feed } from './components/PostFeed'
-import { CPostEditor } from './components/NewPost'
-import { Header } from './components/Header'
-import { InputForm, CRegisterForm, CLoginForm } from './components/LoginRegisterLogout'
 
+import { CShowHeader } from './pages/header/Header'
+import { CRouting } from './components/Routing'
+import {history} from './helpers'
 console.log(store.getState())
 store.subscribe(() => console.log(store.getState()))
 console.log('ABOUT ME', store.getState().auth?.payload?.sub?.id)
-const Routing = ({ token }) => {
 
-  return <>
-    {token ?
-      <Switch>
-        <Route path="/profile/:_id" component={CPageAboutUser} />
-        <Route path="/explore" component={CExplorePosts} />
-        <Route path="/edit/post/:_id" component={CPostEditor} />
-        <Route path="/post/:_id" component={CPost} />
-        <Route path="/feed" component={CPostForFeed} />
-        <Redirect from="/*" to="/feed" />
-      </Switch>
-      :
-      <Switch>
-        <Route path="/login" exact component={CLoginForm} />
-        <Route path="/register" component={CRegisterForm} />
-        <Route path="/input" component={InputForm} />
-        <Redirect from="/*" to="/input" />
-        <CProtectedRoute
-          roles={['anon']}
-          fallback="/*"
-          path="/input"
-          component={InputForm}
-        />
-      </Switch>
-    }
-  </>
-}
-const CRouting = connect((state) => ({
-  token: state.auth?.token,
-}))(Routing)
-
-const ProtectedRoute = ({
-  roles = [],
-  fallback = '/login',
-  component,
-  auth,
-  ...routeProps
-}) => {
-  const WrapperComponent = (renderProps) => {
-    const C = component
-    if (!auth) auth = ['anon']
-    let intersection = auth.filter((x) => roles.includes(x))
-    if (intersection.length == 0) return <Redirect to={fallback} />
-
-    return <C {...renderProps} />
-  }
-  return <Route {...routeProps} component={WrapperComponent} />
-}
-const CProtectedRoute = connect((state) => ({
-  auth: state.auth?.payload?.sub.acl,
-}))(ProtectedRoute)
-
-export const history = createHistory()
 
-const ShowHeader = ({ token }) => (token ? <Header /> : null)
-const CShowHeader = connect((state) => ({
-  token: state.auth?.token,
-}))(ShowHeader)
 
 function App() {
   if (store.getState().auth?.token) {

+ 1 - 1
src/actions/index.js

@@ -11,7 +11,7 @@ import { actionClearExplorePosts } from '../redux/reducers/explore/exploreReduce
 import { actionExploreType } from '../redux/reducers/explore/exploreReducer'
 import { actionClearFeedPosts } from '../redux/reducers/feed/feedReducer'
 
-import { history } from '../App'
+import { history } from '../helpers'
 export const actionAuthLogin = (token) => ({ type: 'AUTH_LOGIN', token })
 export const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' })
 export const getGQL = (url) => (query, variables) =>

+ 74 - 0
src/components/Carousel.js

@@ -0,0 +1,74 @@
+import { Carousel } from 'antd'
+import { LeftCircleFilled, RightCircleFilled } from '@ant-design/icons'
+import photoNotFound from '../materials/photoNotFound.png'
+
+const SampleNextArrow = (props) => {
+    const { onClick } = props
+    return (
+      <div
+        style={{
+          fontSize: '50px',
+          color: '#41607d',
+          position: 'absolute',
+          left: '100%',
+          top: '50%',
+          margin: 'auto',
+          paddingLeft: '20px',
+          textShadow: 'black 1px 0 10px',
+        }}
+        onClick={onClick}
+      >
+        <RightCircleFilled />
+      </div>
+    )
+  }
+  
+  const SamplePrevArrow = (props) => {
+    const {  onClick } = props
+    return (
+      <div
+        style={{
+          color: '#41607d',
+          fontSize: '50px',
+          position: 'absolute',
+          margin: 'auto',
+          right: '100%',
+          top: '50%',
+          paddingRight: '20px',
+        }}
+        onClick={onClick}
+      >
+        <LeftCircleFilled />
+      </div>
+    )
+  }
+  
+  export const MyCarousel = ({ images = [] }) => {
+    return (
+      <>
+        <div className="MyCarousel">
+          <Carousel 
+            effect="fade"
+            arrows
+            nextArrow={<SampleNextArrow />}
+            prevArrow={<SamplePrevArrow />}
+          >
+            {images ? (
+              images?.map(
+                (i, index) =>
+                  i?.url && (
+                    <div key={index}>
+                      <img key={index} className="PostImage" src={'/' + i?.url} />
+                    </div>
+                  ),
+              )
+            ) : (
+              <div >
+                <img className="PostImage" src={photoNotFound} />
+              </div>
+            )}
+          </Carousel>
+        </div>
+      </>
+    )
+  }

+ 253 - 0
src/components/Comment.js

@@ -0,0 +1,253 @@
+import {
+  actionAddFullComment,
+  actionFindSubComment,
+  actionAddSubFullComment,
+} from '../actions'
+import { Tooltip } from 'antd'
+import { connect } from 'react-redux'
+
+import { Input, Button } from 'antd'
+import { SmileOutlined } from '@ant-design/icons'
+import moment from 'moment'
+import React, { useState } from 'react'
+import 'emoji-mart/css/emoji-mart.css'
+import { Picker } from 'emoji-mart'
+import data from 'emoji-mart/data/google.json'
+import { NimblePicker, Emoji } from 'emoji-mart'
+import { LinkToUser } from './LinkToUser'
+import reactStringReplace from 'react-string-replace'
+
+export const AddComment = ({ addComment, postId }) => {
+  const [text, setComment] = useState('')
+  const [showEmojiPicker, setShowEmojiPicker] = useState(false)
+  const addEmoji = ({ colons }) => {
+    setComment((text + ' ' + colons).trim())
+  }
+  return (
+    <>
+      {showEmojiPicker && (
+        <Picker
+          autoFocus={true}
+          style={{
+            color: '#74d2e7',
+            position: 'absolute',
+            bottom: '160px',
+            right: '30px',
+          }}
+          onSelect={(emojiTag) => addEmoji(emojiTag)}
+          set="apple"
+        />
+      )}
+      <Input
+        style={{
+          display: 'flex',
+          width: '40%',
+          marginLeft: '10px',
+          marginRight: '10px',
+        }}
+        size="large"
+        placeholder="Add a comment..."
+        value={text}
+        onChange={(e) => {
+          setComment(e.target.value)
+        }}
+        onPressEnter={(e) => {
+          setComment(e.target.value)
+        }}
+      />
+      <SmileOutlined
+        className="smile-btn"
+        style={{ fontSize: 'xx-large', marginRight: '30px' }}
+        onClick={() => {
+          setShowEmojiPicker(!showEmojiPicker)
+        }}
+      />
+      <Button
+        size="large"
+        disabled={text.length < 1}
+        type="primary"
+        onClick={(e) =>
+          addComment(postId, text) && setComment((e.target.value = ''))
+        }
+      >
+        {' '}
+        Publish{' '}
+      </Button>
+    </>
+  )
+}
+const SpoilerButton = ({ text, close, children }) => {
+  const [opened, setOpened] = useState(close)
+  return (
+    <>
+      <Button
+        onClick={() => {
+          setOpened(!opened)
+        }}
+      >
+        {text}
+      </Button>
+      {opened && children}
+    </>
+  )
+}
+const CommentAuthor = ({ owner }) => (
+  <>
+    <div
+      style={{
+        display: 'flex',
+        flexDirection: 'row',
+        padding: '5px',
+        margin: '5px',
+      }}
+    >
+      <LinkToUser owner={owner} size={'10px'} sizePadding={'0px'} />
+    </div>
+  </>
+)
+
+const CommentForReply = ({ addCommentReply, commentId, postId }) => {
+  const [comment, setComment] = useState('')
+  return (
+    <>
+      <div
+        style={{
+          display: 'flex',
+          flexDirection: 'row',
+          width: '100%',
+          padding: '15px',
+          marginLeft: '40px',
+        }}
+      >
+        <Input
+          placeholder="Add a comment..."
+          value={comment}
+          onChange={(e) => {
+            setComment(e.target.value)
+          }}
+        />
+        <Button
+          disabled={comment.length < 1}
+          type="primary"
+          onClick={() => addCommentReply(postId, commentId, comment)}
+        >
+          {' '}
+          Publish{' '}
+        </Button>
+      </div>
+    </>
+  )
+}
+
+const CommentText = ({ text, close }) => {
+  // const [edit, setEdited] = useState(close)
+  return (
+    <div
+      style={{
+        width: '90%',
+        margin: '20px',
+        paddingLeft: '5px',
+        display: 'flex',
+        alignItems: 'left',
+        justifyContent: 'left',
+        transition: '.3s',
+        boxShadow: '0 5px 10px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22)',
+      }}
+    >
+      {/* <EditOutlined style={{float:'right',  fontSize: 'x-large' }}/> */}
+      <h3 style={{ display: 'block' }}>
+        {' '}
+        {reactStringReplace(text, /:(.+?):/g, (match, i) => (
+          <Emoji emoji={match} set="apple" size={20} />
+        ))}
+      </h3>
+    </div>
+  )
+}
+const CommentData = ({ createdAt }) => {
+  return (
+    <Tooltip
+      color={'#87d068'}
+      style={{ paddingLeft: '10px' }}
+      title={moment(new Date(+createdAt)).format('lll')}
+    >
+      {moment(new Date(+createdAt))
+        .startOf()
+        .fromNow()}
+    </Tooltip>
+  )
+}
+
+export const Comments = ({
+  comments,
+  postId,
+  addCommentReply,
+  commentId,
+  children,
+  close,
+  findSubComment,
+}) => {
+  const [opened, setOpened] = useState(close)
+
+  return (
+    <>
+      {comments
+        ? comments.map((comment) => (
+            <>
+              <div
+                style={{
+                  display: 'flex',
+                  flexDirection: 'row',
+                  width: '100%',
+                  padding: '15px',
+                }}
+              >
+                <CommentAuthor owner={comment.owner} />
+                <CommentText text={comment.text} />
+              </div>
+              <CommentData createdAt={comment.createdAt} />
+              <div style={{ display: 'flex', flexDirection: 'row' }}>
+                <div style={{ display: 'flex', flexDirection: 'column' }}>
+                  <SpoilerButton text={'Reply to'}>
+                    <CommentForReply
+                      addCommentReply={addCommentReply}
+                      commentId={comment._id}
+                      postId={postId}
+                    />
+                  </SpoilerButton>
+                </div>
+                {comment?.answers && comment?.answers?.length ? (
+                  <div style={{ marginLeft: '10px', display: 'inline-block' }}>
+                    <SpoilerButton
+                      style={{ position: 'fixed' }}
+                      text={'More comments'}
+                      onClick={() => findSubComment(commentId)}
+                    >
+                      <Comments
+                        comments={comment.answers}
+                        addCommentReply={addCommentReply}
+                        commentId={comment._id}
+                      ></Comments>
+                    </SpoilerButton>
+                  </div>
+                ) : null}
+              </div>
+            </>
+          ))
+        : null}
+    </>
+  )
+}
+
+export const CComments = connect(
+  (state) => ({
+    postId: state.promise.onePost?.payload?._id,
+    addComment: state.promise?.addComment?.payload,
+    addSubComment: state.promise?.addSubComment,
+  }),
+  {
+    addComment: actionAddFullComment,
+    addCommentReply: actionAddSubFullComment,
+    findSubComment: actionFindSubComment,
+  },
+)(Comments)

+ 1 - 3
src/components/DropZone.js

@@ -15,8 +15,7 @@ export function Basic({ onLoad }) {
       {file.path} - {file.size} bytes
     </li>
   ))
-  console.log('acceptedFiles name', acceptedFiles[0]?.name)
-
+  // console.log('acceptedFiles name', acceptedFiles[0]?.name)
   // console.log('acceptedFiles',acceptedFiles)
   useEffect(() => {
     if (acceptedFiles) onLoad(acceptedFiles)
@@ -32,7 +31,6 @@ export function Basic({ onLoad }) {
     </section>
   )
 }
-const videoRegularExp = / *\.(mp4|mkv|wmv|m4v|mov|avi|flv|webm|flac|mka|m4a|aac|ogg)/
 export const SortableItem = SortableElement(({ url, onRemoveImage, _id}) => {
   return (
     <>

+ 1 - 113
src/components/EditAvatar.js

@@ -3,14 +3,7 @@ import { message, Image, Button } from 'antd'
 import { actionUploadFile, actionSetAvatar, actionUserUpsert, actionUserUpdate } from '../actions'
 import React, { useState, useEffect } from 'react'
 import { Basic, ConstructorModal } from '../helpers'
-const Input = ({ state, onChangeText }) => (
-  <input
-    className="Input"
-    value={state}
-    placeholder={state || ''}
-    onChange={onChangeText}
-  />
-)
+import {Input} from './Input'
 
 const EditAvatar = ({ info, onSaveAvatar, setIsModalVisibleEdit, onFileDrop, fileStatus, myId }) => {
   const [state, setState] = useState(info)
@@ -31,8 +24,6 @@ const EditAvatar = ({ info, onSaveAvatar, setIsModalVisibleEdit, onFileDrop, fil
         && message.success(`Avatar success changed!`)
         && setIsModalVisibleEdit(false)
   }
-  //  =>onSaveUserUpsert(state,myId)
-
 
   return (
     <div>
@@ -79,106 +70,3 @@ export const CEditAvatar = connect(
   },
 )(EditAvatar)
 
-
-const EditInfo = ({ info, myId, onSaveUserUpsert }) => {
-  const [state, setState] = useState(info)
-
-  const [isModalVisibleEdit, setIsModalVisibleEdit] = useState(false);
-  // const [state, setState] = useState(post)
-  // actionChangePassword
-  console.log('all info ', info)
-  const showModalEdit = () => {
-    setIsModalVisibleEdit(true);
-  };
-  const handleCancelEdit = () => {
-    setIsModalVisibleEdit(false)
-  }
-  const onChangeLogin = (event) =>
-    setState({
-      ...state,
-      login: event.target.value,
-    })
-  const onChangeNick = (event) =>
-    setState({
-      ...state,
-      nick: event.target.value,
-    })
-
-  const saveLogin = () => {
-    onSaveUserUpsert(state?.login, myId)
-    && message.success(`Save success changed!`)
-    && setIsModalVisibleEdit(false)
-      // && message.success(`Save success changed!`)
-      // && setIsModalVisibleEdit(false)
-  }
-  const saveNick = () => {
-    onSaveUserUpsert(state?.nick, myId)
-    && message.success(`Save success changed!`)
-    && setIsModalVisibleEdit(false)
-      // && message.success(`Save success changed!`)
-      // && setIsModalVisibleEdit(false)
-  }
-
-  return (
-    <div>
-      <Button
-        type="primary" style={{
-          fontWeight: '600',
-          fontSize: '15px',
-          transition: ".3s",
-          boxShadow: "0 5px 15px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22)",
-        }}
-
-        onClick={showModalEdit}>Edit Setting</Button>
-
-      <ConstructorModal title={'Edit setting'}
-        isModalVisible={isModalVisibleEdit}
-        setIsModalVisible={setIsModalVisibleEdit}
-        handleCancel={handleCancelEdit}
-      >
-
-        <CEditAvatar setIsModalVisibleEdit={setIsModalVisibleEdit} />
-
-        <h2> Edit login </h2>
-        <div style={{ display: 'flex', alignItems: 'center', flexDirection: 'row' }}>
-          <Input
-            state={state?.login || ''}
-            className="Input"
-            onChangeText={onChangeLogin}
-          />
-          <Button size="large" style={{ margin: '10px' }}
-          onClick={saveLogin}
-          disabled={state?.login ? false : true}
-
-            type="primary"> Save login </Button>
-        </div>
-        <h2> Edit nick </h2>
-        <div style={{ display: 'flex', alignItems: 'center', flexDirection: 'row' }}>
-          <Input
-            state={state?.nick || ''}
-            className="Input"
-            onChangeText={onChangeNick}
-          />
-          <Button style={{ margin: '10px' }}
-            disabled={state?.nick ? false : true}
-            onClick={saveNick}
-            size="large"
-            type="primary"
-          >
-            Save nick
-          </Button>
-        </div>
-      
-      </ConstructorModal>
-    </div>
-  )
-}
-export const CEditInfo = connect(
-  (state) => ({
-    myId: state?.auth.payload.sub?.id,
-    info: state?.profileData?.aboutMe,
-  }),
-  {
-    onSaveUserUpsert: actionUserUpdate,
-  },
-)(EditInfo)

+ 0 - 83
src/components/Explore.js

@@ -1,83 +0,0 @@
-import {
-  actionOnePost, actionExplorePosts,
-  actionFullExplorePosts
-} from '../actions'
-import { Row, Col } from 'antd'
-import { Card } from './Post'
-import React, { useEffect,useState } from 'react'
-import { connect } from 'react-redux'
-import {
-  actionClearExplorePosts,
-  actionAllClearExplore
-} from '../redux/reducers/explore/exploreReducer'
-  
-const ExplorePosts = ({ explorePosts = [], onPost, onClearExplore,
-  onExlorePosts,explorePostsCount }) => {
-  const [checkScroll, setScroll] = useState(true)
-  console.log('scroll ', checkScroll)
-  useEffect(() =>
-  {
-    if (checkScroll) {
-    onExlorePosts()
-    
-    setScroll(false)
-    }
-  }, [checkScroll])
-
-  useEffect(() => {
-    
-    document.addEventListener('scroll', scrollHandler)
-
-    return () => {
-      document.removeEventListener('scroll', scrollHandler)
-    onClearExplore()
-    }
-  }, [])
-
-  const scrollHandler = (e) => {
-    if (e.target.documentElement.scrollHeight - (e.target.documentElement.scrollTop + window.innerHeight) < 200) {
-      setScroll(true)
-      
-    }
-  }
-
-    // useEffect(() => {
-    //     onExlorePosts()
-       
-    //   }, [])
-    return (
-    <>
-      <Row>
-            <Col span={18} offset={4}>
-            <div
-            style={{
-              display: 'flex',
-              flexWrap: 'wrap',
-              padding: '20px',
-                margin: '20px',
-                marginTop:'50px'
-            }}
-          >
-            {(explorePosts || [])?.map((item) => (
-              <Card post={item} onPost={onPost} />
-            ))}
-          </div> 
-                
-        </Col>
-            </Row>
-        </>
-    )
-}
-export const CExplorePosts = connect(
-    (state) => ({
-      my_Id: state.auth?.payload?.sub?.id || '',
-      countAllPostsUser: state.promise?.countAllPostsUser?.payload,
-    explorePosts: state.explore?.explorePosts,
-    explorePostsCount:state.explore?.explorePostsCount,
-    }),
-  {
-    onExlorePosts: actionFullExplorePosts,
-      onPost: actionOnePost,
-      onClearExplore:actionClearExplorePosts
-    },
-  )(ExplorePosts)

+ 18 - 19
src/components/Header.js

@@ -4,10 +4,23 @@ import { Avatar, Button } from 'antd'
 import { CSearch } from './Search_Users'
 import { Link } from 'react-router-dom'
 import { connect } from 'react-redux'
-import { AddPost } from './NewPost'
-import React, { useEffect } from 'react'
-import { CLogout } from './LoginRegisterLogout'
+import React, { useEffect,useState } from 'react'
 
+export const AddPost = ({ children }) => {
+  const [state, setState] = useState(false)
+
+  return (
+    <>
+      <Link to={`/edit/post/new`}>
+        <a className="button" onClick={() => setState(!state)}>
+          {' '}
+          +{' '}
+        </a>
+        {!state && children}
+      </Link>
+    </>
+  )
+}
 export const Feed = () => {
   return (
     <>
@@ -18,7 +31,7 @@ export const Feed = () => {
   )
 }
 
-const Recommendations = () => (
+export const Explore = () => (
   <Link to={`/explore`}>
     <a size="large" className="button">
       {' '}
@@ -39,24 +52,10 @@ const User = ({ my_Id, aboutMe: { _id, login, avatar } = {}, onMyPage }) => {
   )
 }
 
-const CUser = connect(
+export const CUser = connect(
   (state) => ({
     my_Id: state.auth?.payload?.sub?.id,
     aboutMe: state.profileData.aboutMe,
   }),
   { onMyPage: actionFullProfilePageUser },
 )(User)
-
-export const Header = () => {
-  return (
-    <section className="Header">
-      <CLogout className="button" />
-      <CSearch />
-      <Feed />
-      <AddPost />
-      <Recommendations />
-
-      <CUser />
-    </section>
-  )
-}

+ 8 - 0
src/components/Input.js

@@ -0,0 +1,8 @@
+export const Input = ({ state, onChangeText }) => (
+    <input
+      className="Input"
+      value={state}
+      placeholder={state || ''}
+      onChange={onChangeText}
+    />
+  )

+ 29 - 19
src/components/Like.js

@@ -4,31 +4,20 @@ import { Link } from 'react-router-dom'
 import user from '../materials/user.png'
 import { HeartOutlined, HeartFilled } from '@ant-design/icons'
 import React, { useState } from 'react'
+import { LinkToUser } from './LinkToUser'
+import {
+  actionAddFullLikeFeed,
+  actionDeleteFullLikeFeed,
+} from '../redux/thunk'
+import { connect } from 'react-redux'
 
 export const Likes = ({ likes }) => {
   return (
     <>
       <div className="Modal">
         {likes &&
-          likes?.map(({ owner: { _id, login, avatar } }) => (
-            <Link to={`/profile/${_id}`}>
-              <Row style={{margin:'10px'}}>
-                <Col offset={1}>
-                {avatar?.url ? (
-              <Avatar
-                style={{ width: '50px', height: '50px' }}
-                src={'/' + avatar?.url}
-              />
-            ) : (
-              <Avatar style={{ width: '50px', height: '50px' }} src={user} />
-            )}
-
-                </Col>
-                <Col offset={2}>
-                  <h3> {login || 'Anon'}</h3>
-                </Col>
-              </Row>
-            </Link>
+          likes?.map(({owner:{_id,login, avatar}}) => (
+            <LinkToUser _id={_id} login={login} avatar={avatar} size={50} padding={'0px'} />
           ))}
       </div>
     </>
@@ -84,3 +73,24 @@ export const Like = ({
     </>
   )
 }
+const AllLikeComponent = ({ my_Id, addLike, deleteLike, likes, postId }) => (
+  <Like
+    my_Id={my_Id}
+    addLike={addLike}
+    deleteLike={deleteLike}
+    likes={likes}
+    postId={postId}
+  >
+    <Likes likes={likes} />
+  </Like>
+)
+
+export const CLike = connect(
+  (state) => ({
+    my_Id: state.auth?.payload?.sub?.id || '',
+  }),
+  {
+    addLike: actionAddFullLikeFeed,
+    deleteLike: actionDeleteFullLikeFeed,
+  },
+)(AllLikeComponent)

+ 40 - 20
src/components/LinkToUser.js

@@ -1,25 +1,45 @@
 import user from '../materials/user.png'
-import { Link} from 'react-router-dom'
-import { Avatar, Col} from 'antd'
+import { Link } from 'react-router-dom'
+import { Avatar, Col, Row } from 'antd'
 
-export const LinkToUser = ({ owner, size, font='15px',padding='10px', sizePadding='20px' }) => {
-    return <Col className="gutter-row" style={{padding:sizePadding}}>
-        <Link to={`/profile/${owner?._id}`} style={{
-            display: 'flex',
-            padding: padding, flexDirection: 'row',
-            fontSize:font
-        }}>
-        {owner?.avatar ? (
+export const LinkToUser = ({
+    _id,
+    avatar,
+    login,
+  size,
+  font = '15px',
+  padding = '10px',
+    onClick, key
+}) => {
+  return (
+    <Row style={{ margin:'10px', marginBottom:'20px' }}>
+      <Link
+        to={`/profile/${_id}`}
+        style={{
+          display: 'flex',
+          padding: padding,
+          flexDirection: 'row',
+          fontSize: font,
+              }}
+              onClick={onClick}
+              key={key}
+      >
+        <Col offset={1} className="gutter-row" >
+          {avatar ? (
             <Avatar
-               size={size}
-                    src={'/' + owner?.avatar?.url}
-                    style={{marginRight:'5px'}}
+              size={size}
+              src={'/' + avatar?.url}
+              style={{ marginRight: '5px' }}
             />
-        ) : (
-            <Avatar size={size} src={user}  style={{marginRight:'5px'}} />
-        )}
-        <h2> {owner?.login || 'Anon'}</h2>
-        </Link>
-    </Col>
+          ) : (
+            <Avatar size={size} src={user} style={{ marginRight: '5px' }} />
+          )}
+        </Col>
+        <Col offset={2}>
+          <h3> {login || 'Anon'}</h3>
+        </Col>
+      </Link>
+    </Row>
+  )
 }
-export default LinkToUser
+export default LinkToUser

+ 0 - 45
src/components/ListFollowers.js

@@ -1,45 +0,0 @@
-import { ConstructorModal } from '../helpers'
-import { ResultUserFind } from '../components/Search_Users'
-import React, { useState } from 'react'
-export const ListFollowers = ({
-  aboutUserFollowers,
-  followers,
-  onPageData,
-}) => {
-  const [isModalVisibleFollowers, setIsModalVisibleFollowers] = useState(false)
-
-  const showModalFollowers = () => {
-    setIsModalVisibleFollowers(true)
-  }
-  const handleCancelFollowers = () => {
-    setIsModalVisibleFollowers(false)
-  }
-  return (
-    <>
-      {followers?.length > 0 ? (
-        <h3
-          style={{ cursor: 'pointer', marginLeft: '20px' }}
-          onClick={showModalFollowers}
-        >
-          {followers.length} followers{' '}
-        </h3>
-      ) : (
-        <h3 style={{ marginLeft: '20px' }}> 0 followers </h3>
-      )}
-
-      <ConstructorModal
-        title={'Followers'}
-        isModalVisible={isModalVisibleFollowers}
-        setIsModalVisible={setIsModalVisibleFollowers}
-      >
-        <ResultUserFind
-          size={'40px'}
-          onPageData={onPageData}
-          handleCancel={handleCancelFollowers}
-          userFind={aboutUserFollowers}
-        />
-      </ConstructorModal>
-    </>
-  )
-}
-export default ListFollowers

+ 0 - 47
src/components/ListFollowing.js

@@ -1,47 +0,0 @@
-import { Avatar, Col } from 'antd'
-import { ConstructorModal } from '../helpers'
-import { ResultUserFind } from '../components/Search_Users'
-import React, { useState } from 'react'
-
-export const ListFollowing = ({
-  aboutUserFollowing,
-  following,
-  onPageData,
-}) => {
-  const [isModalVisibleFollowing, setIsModalVisibleFollowing] = useState(false)
-
-  const showModalFollowing = () => {
-    setIsModalVisibleFollowing(true)
-  }
-  const handleCancelFollowing = () => {
-    setIsModalVisibleFollowing(false)
-  }
-  return (
-    <>
-      {following?.length > 0 ? (
-        <h3
-          style={{ cursor: 'pointer', marginLeft: '20px' }}
-          onClick={showModalFollowing}
-        >
-          {following.length} following{' '}
-        </h3>
-      ) : (
-        <h3 style={{ marginLeft: '20px' }}> 0 following </h3>
-      )}
-
-      <ConstructorModal
-        title={'Following'}
-        isModalVisible={isModalVisibleFollowing}
-        setIsModalVisible={setIsModalVisibleFollowing}
-      >
-        <ResultUserFind
-          size={'40px'}
-          onPageData={onPageData}
-          handleCancel={handleCancelFollowing}
-          userFind={aboutUserFollowing}
-        />
-      </ConstructorModal>
-    </>
-  )
-}
-export default ListFollowing

+ 46 - 0
src/components/ListOfUsers.js

@@ -0,0 +1,46 @@
+import { ConstructorModal } from '../helpers'
+import { ResultUserFind } from './Search_Users'
+import React, { useState } from 'react'
+export const ListOfUsers = ({
+  listResult,
+  listUsers,
+  onPageData,
+  text
+}) => {
+  const [isModalVisible, setIsModalVisible] = useState(false)
+
+  const showModal = () => {
+    setIsModalVisible(true)
+  }
+  const handleCancel = () => {
+    setIsModalVisible(false)
+  }
+  return (
+    <>
+      {listUsers?.length > 0 ? (
+        <h3
+          style={{ cursor: 'pointer', marginLeft: '20px' }}
+          onClick={showModal}
+        >
+          {listUsers.length} {text} {' '}
+        </h3>
+      ) : (
+        <h3 style={{ marginLeft: '20px' }}> 0 {text} </h3>
+      )}
+
+      <ConstructorModal
+        title={text[0].toUpperCase()+ text.slice(1)}
+        isModalVisible={isModalVisible}
+        setIsModalVisible={setIsModalVisible}
+      >
+        <ResultUserFind
+          size={'40px'}
+          onPageData={onPageData}
+          handleCancel={handleCancel}
+          userFind={listResult}
+        />
+      </ConstructorModal>
+    </>
+  )
+}
+export default ListOfUsers

+ 13 - 140
src/components/Post.js

@@ -5,25 +5,22 @@ import {
   actionDeleteFullLike,
   actionAddFullLike,
 } from '../actions'
-import photoNotFound from '../materials/photoNotFound.png'
-import { LeftCircleFilled, RightCircleFilled } from '@ant-design/icons'
-import { Carousel, Avatar, Divider, Input, Button } from 'antd'
+
+import { Avatar, Divider, Input, Button } from 'antd'
 import user from '../materials/user.png'
 import { connect } from 'react-redux'
 import { Row, Col } from 'antd'
-import { CComments, AddComment } from '../components/Post_Comment'
-import { CPostEditor } from '../components/NewPost'
+import { CComments, AddComment } from './Comment'
+import { CPostEditor } from '../pages/createAndEditPost/CreateAndEditPost'
 import { actionFullOnePost } from '../redux/reducers/post/postReducer'
-import { Like, Likes } from './Like'
+import { CLike} from './Like'
 import { ConstructorModal } from '../helpers'
 import React, { useState, useEffect } from 'react'
 import {
-
   actionAddFullCommentFeed,
-  actionAddFullLikeFeed,
-  actionDeleteFullLikeFeed,
 } from '../redux/thunk'
-import {LinkToUser} from './LinkToUser'
+import { LinkToUser } from './LinkToUser'
+import { MyCarousel } from './Carousel'
 const EditMyPost = ({ _id }) => {
   return (
     <>
@@ -39,103 +36,7 @@ const EditMyPost = ({ _id }) => {
     </>
   )
 }
-export const Card = ({ post }) => (
-  <>
-    <Link key={post?._id} to={`/post/${post?._id}`}>
-      {post?.images && post?.images[0] && post.images[0]?.url ? (
-        <img
-          className="Card"
-          src={'/' + post.images[0].url}
-          style={{
-            width: '250px',
-            height: '250px',
-            objectFit: 'cover',
-          }}
-        />
-      ) : (
-        <img
-          className="Card"
-          src={photoNotFound}
-          style={{
-            width: '250px',
-            height: '250px',
-            objectFit: 'cover',
-          }}
-        />
-      )}
-    </Link>
-  </>
-)
-const SampleNextArrow = (props) => {
-  const { onClick } = props
-  return (
-    <div
-      style={{
-        fontSize: '50px',
-        color: '#41607d',
-        position: 'absolute',
-        left: '100%',
-        top: '50%',
-        margin: 'auto',
-        paddingLeft: '20px',
-        textShadow: 'black 1px 0 10px',
-      }}
-      onClick={onClick}
-    >
-      <RightCircleFilled />
-    </div>
-  )
-}
 
-const SamplePrevArrow = (props) => {
-  const {  onClick } = props
-  return (
-    <div
-      style={{
-        color: '#41607d',
-        fontSize: '50px',
-        position: 'absolute',
-        margin: 'auto',
-        right: '100%',
-        top: '50%',
-        paddingRight: '20px',
-      }}
-      onClick={onClick}
-    >
-      <LeftCircleFilled />
-    </div>
-  )
-}
-
-export const MyCarousel = ({ images = [] }) => {
-  return (
-    <>
-      <div className="MyCarousel">
-        <Carousel 
-          effect="fade"
-          arrows
-          nextArrow={<SampleNextArrow />}
-          prevArrow={<SamplePrevArrow />}
-        >
-          {images ? (
-            images?.map(
-              (i, index) =>
-                i?.url && (
-                  <div key={index}>
-                    <img key={index} className="PostImage" src={'/' + i?.url} />
-                  </div>
-                ),
-            )
-          ) : (
-            <div >
-              <img className="PostImage" src={photoNotFound} />
-            </div>
-          )}
-        </Carousel>
-      </div>
-    </>
-  )
-}
 
 export const PagePost = ({
   my_Id,
@@ -177,20 +78,12 @@ export const PagePost = ({
         <Col span={8}>
           <div style={{ display: 'flex', flexDirection: 'row', marginTop:'100px' }}>
             
-            <LinkToUser owner={onePost?.owner} size={'50px'} padding={'0px'} />
-            {/* {my_Id === onePost?.owner?._id && <EditMyPost _id={_id} />} */}
-            {/* {onePost?.owner?.avatar ? (
-              <Avatar
-                style={{ width: '50px', height: '50px' }}
-                src={'/' + onePost?.owner?.avatar?.url}
-              />
-            ) : (
-              <Avatar style={{ width: '50px', height: '50px' }} src={user} />
-            )}
-            <h1 style={{ marginLeft: '20px' }}>
-              {' '}
-              {onePost?.owner?.login || 'Anon'}
-            </h1> */}
+            <LinkToUser
+              _id={onePost?.owner?._id}
+              login={onePost?.owner?.login}
+              avatar={onePost?.owner?.avatar}
+              key={_id}
+            size={50} padding={'0px'} />
             <Row span={1}>
               {my_Id === onePost?.owner?._id && <EditMyPost _id={_id} />}
             </Row>
@@ -231,23 +124,3 @@ export const CPost = connect(
   },
 )(PagePost)
 
-const AllLikeComp = ({ my_Id, addLike, deleteLike, likes, postId }) => (
-  <Like
-    my_Id={my_Id}
-    addLike={addLike}
-    deleteLike={deleteLike}
-    likes={likes}
-    postId={postId}
-  >
-    <Likes likes={likes} />
-  </Like>
-)
-export const CLike = connect(
-  (state) => ({
-    my_Id: state.auth?.payload?.sub?.id || '',
-  }),
-  {
-    addLike: actionAddFullLikeFeed,
-    deleteLike: actionDeleteFullLikeFeed,
-  },
-)(AllLikeComp)

+ 30 - 0
src/components/PostCard.js

@@ -0,0 +1,30 @@
+import photoNotFound from '../materials/photoNotFound.png'
+import { Link } from 'react-router-dom'
+
+export const Card = ({ post }) => (
+    <>
+      <Link key={post?._id} to={`/post/${post?._id}`}>
+        {post?.images && post?.images[0] && post.images[0]?.url ? (
+          <img
+            className="Card"
+            src={'/' + post.images[0].url}
+            style={{
+              width: '250px',
+              height: '250px',
+              objectFit: 'cover',
+            }}
+          />
+        ) : (
+          <img
+            className="Card"
+            src={photoNotFound}
+            style={{
+              width: '250px',
+              height: '250px',
+              objectFit: 'cover',
+            }}
+          />
+        )}
+      </Link>
+    </>
+  )

+ 0 - 177
src/components/Post_Comment.js

@@ -1,177 +0,0 @@
-import {
- actionAddFullComment,
-  actionFindSubComment, actionAddSubFullComment
-} from '../actions'
-import { Tooltip } from 'antd'
-import { connect } from 'react-redux'
-
-import { Input, Button } from 'antd';
-import {SmileOutlined} from '@ant-design/icons'
-import moment from 'moment';
-import React, { useState } from 'react'
-import 'emoji-mart/css/emoji-mart.css'
-import { Picker } from 'emoji-mart'
-import data from 'emoji-mart/data/google.json'
-import { NimblePicker, Emoji } from 'emoji-mart'
-import {LinkToUser} from './LinkToUser'; 
-import reactStringReplace from 'react-string-replace'
-
-export const AddComment = ({ addComment, postId }) => {
-  const [text, setComment] = useState('')
-  const [showEmojiPicker, setShowEmojiPicker] = useState(false)
-  const addEmoji = ({ colons }) => {
-    setComment((text + ' ' + colons).trim());
-  };
-
-  return (
-    <>
-      {
-        showEmojiPicker && <Picker autoFocus={true}
-          style={{ color: '#74d2e7',position: 'absolute', bottom: '160px', right: '30px' }}
-          onSelect={emojiTag => addEmoji(emojiTag)} set="apple" />
-      }
-      <Input style={{ display:'flex',width:'40%',marginLeft:'10px', marginRight:'10px' }} size="large" placeholder='Add a comment...' 
-          value={text} onChange={e => { setComment(e.target.value) }}
-        onPressEnter={e => { setComment(e.target.value) }}/> 
-         <SmileOutlined className='smile-btn' style={{ fontSize: 'xx-large', marginRight:'30px' }} 
-          onClick={() => {
-            setShowEmojiPicker(!showEmojiPicker)
-          }}/>
-      <Button 
-        size="large" disabled={text.length < 1} type="primary"
-          onClick={(e) => addComment(postId, text)&&setComment(e.target.value="")}> Publish </Button>
-        </>
-    )
-      
-}
-const SpoilerButton = ({text, close, children }) => {
-    const [opened, setOpened] = useState(close)
-    return (
-      <>
-        <Button 
-          onClick={() => {
-            setOpened(!opened)
-          }}>
-          {text}
-        </Button>
-          {opened && children}
-      </>
-    )
-  }
-  const CommentAuthor = ({owner}) =>
-  <>
-      <div style={{ display: 'flex', flexDirection: 'row', padding: '5px', margin: '5px' }}>
-        
-        <LinkToUser owner={owner} size={'10px'} sizePadding={'0px' }/>
-  
-      </div>
-  </>
-
-
-const CommentForReply =({addCommentReply, commentId, postId})=>{
-    const [comment, setComment]=useState('')
-    return (
-     <>
-      <div style={{display: 'flex', flexDirection: 'row', width:'100%', padding: '15px', marginLeft:'40px'}}>
-          
-        <Input  placeholder='Add a comment...' 
-            value={comment} onChange={e => { setComment(e.target.value) }} />
-        <Button  disabled={comment.length<1} type="primary" onClick={()=>
-            addCommentReply(postId, commentId, comment)
-          
-          }> Publish </Button>
-          </div>
-      </>
-    )
-  }
-  
-  const CommentText = ({ text,close }) => {
-    // const [edit, setEdited] = useState(close)
-    return (
-      <div style={{
-        width: '90%',
-        margin: "20px",
-        paddingLeft:'5px',
-        display: "flex",
-        alignItems: "left",
-justifyContent: "left",
-transition: ".3s",
-boxShadow: "0 5px 10px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22)"
-      }}>
-   {/* <EditOutlined style={{float:'right',  fontSize: 'x-large' }}/> */}
-        <h3 style={{display:'block'}}>  {reactStringReplace(text, /:(.+?):/g, (match, i) => (
-          <Emoji emoji={match}  set='apple' size={20}/> ))}
-        </h3>
-       
-      </div>
-    )
-  }
-  const CommentData = ({ createdAt }) => {
-    return <Tooltip color={'#87d068'} style={{ paddingLeft: '10px' }} title={moment(new Date(+createdAt)).format('lll')} >
-    {moment(new Date(+createdAt)).startOf().fromNow()}
-  </ Tooltip>
-}
-  
-
- export const Comments = ({ comments,postId, addCommentReply, commentId,children,close,findSubComment }) => {
-    const [opened, setOpened] = useState(close)
-   
-    return (
-      <>
-        {/* {console.log('длина ', comments?.length)} */}
-       
-        {
-        
-        comments ? (comments).map((comment) =>
-        <>
-      <div style={{display: 'flex', flexDirection: 'row', width:'100%', padding: '15px'}}>
-          <CommentAuthor owner={comment.owner} />
-            <CommentText text={comment.text} />
-            </div>
-            {/* <h3 style={{ marginRight: '2%' }}>  {text} </h3> */}
-            {/* <h3> мой айди {_id}</h3> */}
-          {/* </div> */}
-          <CommentData createdAt={comment.createdAt} />
-          <div style={{display: 'flex', flexDirection: 'row'}}>
-          
-             <div style={{display: 'flex', flexDirection: 'column' }}>
-          <SpoilerButton text={'Reply to'} >
-               {/* <Input />
-               <button> send </button> */}
-                  
-                     
-                  <CommentForReply addCommentReply={addCommentReply} commentId={comment._id} postId={postId}/>
-                     
-              </SpoilerButton>
-            </div> 
-          {comment?.answers && comment?.answers?.length ?
-            <div style={{ marginLeft: '10px', display:'inline-block'}}>
-                
-                          <SpoilerButton style={{ position: 'fixed' }} text={'More comments'} onClick={() => findSubComment(commentId)}>
-                              <Comments comments={comment.answers} addCommentReply={addCommentReply} commentId={comment._id} >
-
-                              </Comments>
-                          </SpoilerButton>
-                          
-                      </div>
-                      : null
-            }
-          </div>
-        </>
-      ) : null
-  }
-      </>
-    ) 
-}
-
-export const CComments = connect((state) => ({
-    postId: state.promise.onePost?.payload?._id,
-    addComment: state.promise?.addComment?.payload,
-    addSubComment: state.promise?.addSubComment,
-}),
-    {
-        addComment: actionAddFullComment, 
-        addCommentReply: actionAddSubFullComment,
-      findSubComment: actionFindSubComment,
-     
-    })(Comments)

+ 62 - 0
src/components/Routing.js

@@ -0,0 +1,62 @@
+import { InputForm, CRegisterForm, CLoginForm } from './LoginRegisterLogout'
+import { Router, Route, Redirect, Switch } from 'react-router-dom'
+import { CExplorePosts } from '../pages/explorePosts/ExplorePosts'
+import { CPostForFeed, Feed } from '../pages/feedPosts/FeedPosts'
+import { CPostEditor } from '../pages/createAndEditPost/CreateAndEditPost'
+import { CPageAboutUser } from '../pages/profilePage/ProfilePageUser'
+import { CPost } from './Post'
+import { Provider, connect } from 'react-redux'
+
+const Routing = ({ token }) => {
+
+    return <>
+      {token ?
+        <Switch>
+          <Route path="/profile/:_id" component={CPageAboutUser} />
+          <Route path="/explore" component={CExplorePosts} />
+          <Route path="/edit/post/:_id" component={CPostEditor} />
+          <Route path="/post/:_id" component={CPost} />
+          <Route path="/feed" component={CPostForFeed} />
+          <Redirect from="/*" to="/feed" />
+        </Switch>
+        :
+        <Switch>
+          <Route path="/login" exact component={CLoginForm} />
+          <Route path="/register" component={CRegisterForm} />
+          <Route path="/input" component={InputForm} />
+          <Redirect from="/*" to="/input" />
+          <CProtectedRoute
+            roles={['anon']}
+            fallback="/*"
+            path="/input"
+            component={InputForm}
+          />
+        </Switch>
+      }
+    </>
+  }
+ export const CRouting = connect((state) => ({
+    token: state.auth?.token,
+  }))(Routing)
+  
+  const ProtectedRoute = ({
+    roles = [],
+    fallback = '/login',
+    component,
+    auth,
+    ...routeProps
+  }) => {
+    const WrapperComponent = (renderProps) => {
+      const C = component
+      if (!auth) auth = ['anon']
+      let intersection = auth.filter((x) => roles.includes(x))
+      if (intersection.length == 0) return <Redirect to={fallback} />
+  
+      return <C {...renderProps} />
+    }
+    return <Route {...routeProps} component={WrapperComponent} />
+  }
+  const CProtectedRoute = connect((state) => ({
+    auth: state.auth?.payload?.sub.acl,
+  }))(ProtectedRoute)
+  

+ 7 - 30
src/components/Search_Users.js

@@ -6,43 +6,20 @@ import { actionSearchUser } from '../actions'
 import {UserOutlined } from '@ant-design/icons'
 
 import { actionFullProfilePageUser } from '../redux/thunk'
+import LinkToUser from './LinkToUser'
 export const ResultUserFind = ({
   userFind = [],
-  handleCancel,
+  handleCancel, 
+ 
 }) => { 
+    console.log('user find', userFind) 
   return (
     <div className="ResultUserFind">
       {userFind?.map(({ _id, login, avatar }) => (
-        <Link to={`/profile/${_id}`} onClick={handleCancel} key={_id}>
-          <Row>
-            <Col offset={1}>
-              {avatar?.url ? (
-                <Avatar
-                  style={{
-                    width: '50px',
-                    height: '50px',
-                    marginBottom: '10px',
-                  }}
-                  src={'/' + avatar?.url}
-                />
-              ) : (
-                <Avatar
-                  style={{
-                    width: '50px',
-                    height: '50px',
-                    marginBottom: '10px',
-                  }}
-                  src={user}
-                />
-              )}
-            </Col>
-            <Col offset={1}>
-              <h3 style={{ marginBottom: '20px' }}> {login || 'Anon'}</h3>
-            </Col>
-          </Row>
-        </Link>
+       
+        <LinkToUser _id={_id} login={login} avatar={avatar} size={40} padding={'0px'} onClick={handleCancel} key={_id} />
       ))}
-    </div>
+      </div>
   )
 }
 const SearchUser = ({ my_Id, onSearch, searchUser, onPageData }) => {

+ 52 - 0
src/components/Subscribe.js

@@ -0,0 +1,52 @@
+import {
+    actionFullUnSubscribe,
+    actionFullSubscribe,
+} from '../actions'
+import { Button} from 'antd'
+import { connect } from 'react-redux'
+  
+const Subscribe = ({
+    my_Id,
+    deleteSubscribe,
+    aboutMeFollowing = [],
+    addSubscribe,
+    followId,
+  }) => {
+    const checkFollowId = aboutMeFollowing?.find(
+      (follower) => follower?._id === followId,
+    )?._id
+    return (
+      <>
+        <div style={{ display: 'flex' }}>
+          {checkFollowId ? (
+            <Button
+              size="large" type="primary"
+               danger
+              onClick={() => deleteSubscribe(my_Id, followId)}
+            >
+              Unsubscribe
+            </Button>
+          ) : (
+            <Button
+              size="large"
+                type="primary"
+                primary
+              onClick={() => addSubscribe(my_Id, followId)}
+            >
+              Subscribe
+            </Button>
+          )}
+        </div>
+      </>
+    )
+}
+export const CSubscribe = connect((state) => ({
+    my_Id: state.auth?.payload?.sub?.id,
+    aboutMeFollowing: state.profileData?.aboutMe?.following,
+    followId: state.profilePage?.aboutUser?._id,
+}),
+    {
+        addSubscribe: actionFullSubscribe,
+        deleteSubscribe: actionFullUnSubscribe,
+}
+)(Subscribe)

+ 3 - 0
src/helpers/index.js

@@ -2,6 +2,9 @@ import { Modal,Button } from 'antd'
 import { useDropzone } from 'react-dropzone'
 import React, {useEffect } from 'react'
 import { UploadOutlined } from '@ant-design/icons'
+import createHistory from 'history/createBrowserHistory'
+
+export const history = createHistory()
 
 export const ConstructorModal = ({
   title,

+ 45 - 61
src/components/NewPost.js

@@ -5,46 +5,18 @@ import {
   actionUploadFiles,
   actionPostUpsert,
   actionClearPromise,
-} from '../actions'
-import { actionClearPostsOne } from '../redux/reducers/post/postReducer'
+} from '../../actions'
+import { actionClearPostsOne } from '../../redux/reducers/post/postReducer'
 import { Button, message } from 'antd'
-import { Basic, SortableContainer, SortableItem } from '../components/DropZone'
+import {
+  Basic,
+  SortableContainer,
+  SortableItem,
+} from '../../components/Dropzone'
 import { arrayMoveImmutable } from 'array-move'
 import { Row, Col } from 'antd'
-
-import { history } from '../App'
-export const PageCreatePost = () => (
-  <div style={{ background: '#FFFACD' }}>
-    <h2>Edit Post</h2>
-    <CPostEditor />
-  </div>
-)
-
-export const AddPost = ({ children }) => {
-  const [state, setState] = useState(false)
-
-  return (
-    <>
-      <Link to={`/edit/post/new`}>
-        <a className="button" onClick={() => setState(!state)}>
-          {' '}
-          +{' '}
-        </a>
-        {!state && children}
-      </Link>
-    </>
-  )
-}
-
-const Input = ({ state, onChangeText }) => (
-  <input
-    className="Input"
-    value={state}
-    placeholder={state || ''}
-    onChange={onChangeText}
-  />
-)
-
+import { history } from '../../helpers'
+import { Input } from '../../components/Input'
 const PostEditor = ({
   match: {
     params: { _id },
@@ -142,35 +114,40 @@ const PostEditor = ({
   }, [])
   const checkLength = () => {
     if (state?.images?.length > 8) {
-      console.log('state?.images?.length',state?.images?.length)
+      console.log('state?.images?.length', state?.images?.length)
       message.error('Error, upload Max 8 elements')
-      state["images"]=[]
-        return false
-    }
-    else {
-      return  <h3> {state?.images.length}/ 8</h3>
+      state['images'] = []
+      return false
+    } else {
+      return <h3> {state?.images.length} / 8</h3>
     }
-}
+  }
+
   return (
     <section className="Post">
       <Row>
-        <Col span={12} offset={7}>
+        <Col span={12} offset={6}>
           <Basic onLoad={onFileDrop} />
           <Col offset={1}>
-          <SortableContainer onSortEnd={onSortEnd} style={{ with: '300px' }}>
-          
-            { state?.images?.length<8 && (state?.images || []).map(({ _id, url }, index) => (
-             <SortableItem
-                key={`item-${_id}`}
-                url={url}
-                index={index}
-                onRemoveImage={onRemoveImage}
-                _id={_id}
-              /> 
-            ))}
-          </SortableContainer>
+         
+              <SortableContainer
+                onSortEnd={onSortEnd}
+                style={{ with: '300px' }}
+              >
+                {state?.images?.length < 8 &&
+                  (state?.images || []).map(({ _id, url }, index) => (
+                    <SortableItem
+                      key={`item-${_id}`}
+                      url={url}
+                      index={index}
+                      onRemoveImage={onRemoveImage}
+                      _id={_id}
+                    />
+                  ))}
+              </SortableContainer>
+           
             {checkLength()}
-            </Col>
+          </Col>
         </Col>
       </Row>
 
@@ -188,9 +165,16 @@ const PostEditor = ({
         onChangeText={onChangeText}
       />
       <br />
-      <center>
+      <Col offset={5}>
         <Button
-          style={{ width: '200px', margin: '10px' }}
+          style={{
+            display: 'flex',
+            margin: '10px',
+            alignItems: 'center',
+            alignContent: 'center',
+            justifyContent: 'center',
+            width: '200px',
+          }}
           disabled={disabledBtn}
           onClick={savePost}
           size="large"
@@ -198,7 +182,7 @@ const PostEditor = ({
         >
           Save
         </Button>
-      </center>
+      </Col>
     </section>
   )
 }

+ 89 - 0
src/pages/explorePosts/ExplorePosts.js

@@ -0,0 +1,89 @@
+import {
+    actionOnePost,
+    actionExplorePosts,
+    actionFullExplorePosts,
+  } from '../../actions'
+  import { Row, Col } from 'antd'
+  import { Card } from '../../components/PostCard'
+  import React, { useEffect, useState } from 'react'
+  import { connect } from 'react-redux'
+  import {
+    actionClearExplorePosts,
+    actionAllClearExplore,
+  } from '../../redux/reducers/explore/exploreReducer'
+  
+  const ExplorePosts = ({
+    explorePosts = [],
+    onPost,
+    onClearExplore,
+    onExlorePosts,
+    explorePostsCount,
+  }) => {
+    const [checkScroll, setScroll] = useState(true)
+    console.log('scroll ', checkScroll)
+    useEffect(() => {
+      if (checkScroll) {
+        onExlorePosts()
+  
+        setScroll(false)
+      }
+    }, [checkScroll])
+  
+    useEffect(() => {
+      document.addEventListener('scroll', scrollHandler)
+  
+      return () => {
+        document.removeEventListener('scroll', scrollHandler)
+        onClearExplore()
+      }
+    }, [])
+  
+    const scrollHandler = (e) => {
+      if (
+        e.target.documentElement.scrollHeight -
+          (e.target.documentElement.scrollTop + window.innerHeight) <
+        200
+      ) {
+        setScroll(true)
+      }
+    }
+    // useEffect(() => {
+    //     onExlorePosts()
+  
+    //   }, [])
+    return (
+      <>
+        <Row>
+          <Col span={18} offset={4}>
+            <div
+              style={{
+                display: 'flex',
+                flexWrap: 'wrap',
+                padding: '20px',
+                margin: '20px',
+                marginTop: '50px',
+              }}
+            >
+              {(explorePosts || [])?.map((item) => (
+                <Card post={item} onPost={onPost} />
+              ))}
+            </div>
+          </Col>
+        </Row>
+      </>
+    )
+  }
+  export const CExplorePosts = connect(
+    (state) => ({
+      my_Id: state.auth?.payload?.sub?.id || '',
+      countAllPostsUser: state.promise?.countAllPostsUser?.payload,
+      explorePosts: state.explore?.explorePosts,
+      explorePostsCount: state.explore?.explorePostsCount,
+    }),
+    {
+      onExlorePosts: actionFullExplorePosts,
+      onPost: actionOnePost,
+      onClearExplore: actionClearExplorePosts,
+    },
+  )(ExplorePosts)
+  

+ 9 - 10
src/components/PostFeed.js

@@ -11,7 +11,7 @@ import {
   actionAddFullLikeForFeed,
   actionDeleteFullLikeForFeed,
   actionAddFullLike,
-} from '../actions'
+} from '../../actions'
 import {
   actionFullFeed,
   actionClearFeedPosts,
@@ -19,19 +19,18 @@ import {
   actionAddFullLikeFeed,
   actionDeleteFullLikeFeed,
  
-} from '../redux/thunk'
-import {actionFullClearFeedPosts} from '../redux/reducers/feed/feedReducer'
+} from '../../redux/thunk'
+import {actionFullClearFeedPosts} from '../../redux/reducers/feed/feedReducer'
 import { Link } from 'react-router-dom'
 import { Provider, connect } from 'react-redux'
 import { Upload, Button, DatePicker, Space } from 'antd'
-import user from '../materials/user.png'
 import { Avatar, Image, Divider, Radio } from 'antd'
-import { CPost, MyCarousel } from './Post'
+import { CPost } from '../../components/Post'
 import { Row, Col } from 'antd'
-import LinkToUser from './LinkToUser'
-import { AddComment, Comments } from './Post_Comment'
-import { Like, Likes } from './Like'
-
+import LinkToUser from '../../components/LinkToUser'
+import { AddComment, Comments } from '../../components/Comment'
+import { Like, Likes } from '../../components/Like'
+import { MyCarousel } from '../../components/Carousel'
 const MyPostFeed = ({
   profileData,
   postsFeed = [],
@@ -85,7 +84,7 @@ const MyPostFeed = ({
               {(postsFeed || []).map(
                 ({ _id, images, title, text, owner, comments, likes }) => (
                   <div className="PostFeed" >
-                    <LinkToUser owner={owner} size="70px" />
+                    <LinkToUser _id={owner?._id} key={_id} login={owner?.login} avatar={owner?.avatar} size={50} />
                     <MyCarousel images={images} style={{ marginTop: '60px' }} />
                     <h1 className='Title'> Title: {title || ''}</h1>
                     <h1  className='Title'> Text: {text || ''}</h1>

+ 23 - 0
src/pages/header/Header.js

@@ -0,0 +1,23 @@
+
+import { CLogout } from '../../components/LoginRegisterLogout'
+import { CSearch } from '../../components/Search_Users'
+import { Feed, AddPost, Explore, CUser } from '../../components/Header'
+import { connect } from 'react-redux'
+
+export const Header = () => {
+    return (
+      <section className="Header">
+        <CLogout className="button" />
+        <CSearch />
+        <Feed />
+        <AddPost />
+        <Explore />
+        <CUser />
+      </section>
+    )
+  }
+  
+const ShowHeader = ({ token }) => (token ? <Header /> : null)
+export const CShowHeader = connect((state) => ({
+  token: state.auth?.token,
+}))(ShowHeader)

+ 22 - 99
src/components/User.js

@@ -1,36 +1,15 @@
-import {
-  actionOnePost,
-  actionUploadFile,
-  actionFullUnSubscribe,
-  actionFullSubscribe,
-} from '../actions'
-import user from '../materials/user.png'
+import { actionOnePost, actionUploadFile } from '../../actions'
+import user from '../../materials/user.png'
 import React, { useState, useEffect } from 'react'
-import { Card } from './Post'
-import ListFollowing from './ListFollowing'
-import ListFollowers from './ListFollowers'
-
+import { Card } from '../../components/PostCard'
+import ListOfUsers from '../../components/ListOfUsers'
 import { connect } from 'react-redux'
-import { Avatar, Button} from 'antd'
-import {
-  actionFullProfilePageUser,
- 
-} from '../redux/thunk'
-import { actionRemoveDataUser } from '../redux/reducers/profileData/profileReducer'
+import { Avatar, Button } from 'antd'
+import { actionFullProfilePageUser } from '../../redux/thunk'
 import { Row, Col } from 'antd'
-import { CEditInfo } from '../components/EditAvatar'
+import { CSubscribe } from '../../components/Subscribe'
+import { CEditSetting } from '../setting/Setting'
 
-export const EditAccount = ({ open, children }) => {
-  const [opened, setOpened] = useState(open)
-  return (
-    <>
-      <button style={{ width: '100px' }} onClick={setOpened(!opened)}>
-        Edit account
-      </button>
-      {opened && children}
-    </>
-  )
-}
 export const PageAboutUser = ({
   match: {
     params: { _id },
@@ -38,19 +17,11 @@ export const PageAboutUser = ({
   my_Id,
   aboutUser: { login, nick, createdAt, avatar, followers, following } = {},
   allPosts,
-  followId,
   onPost,
-  addSubscribe,
-  deleteSubscribe,
-  onePost,
   onAboutUser,
-  aboutUserFollowers = [],
   onPageData,
-  aboutUserFollowing = [],
-  aboutMeFollowing,
   countAllPostsUser,
 }) => {
-
   useEffect(() => {
     onAboutUser(_id)
     // console.log('USER DATA ', login, _id)
@@ -104,28 +75,28 @@ export const PageAboutUser = ({
                     <h3> 0 posts </h3>
                   )}
 
-                  <ListFollowers aboutUserFollowers={aboutUserFollowers}
-                    followers={followers} onPageData={onPageData} />
-
-                  <ListFollowing aboutUserFollowing={aboutUserFollowing}
-                    following={following} onPageData={onPageData} />
+                  <ListOfUsers
+                    listResult={followers}
+                    listUsers={followers}
+                                      onPageData={onPageData}
+                                      text={'followers'}
+                  />
 
+                  <ListOfUsers
+                   listResult={following}
+                   listUsers={following}
+                                     onPageData={onPageData}
+                                     text={'following'}
+                  />
                 </div>
                 <h3> nick: {nick == null ? login : nick}</h3>
                 {checkMyId ? (
                   <>
-                    <CEditInfo/>
+                    <CEditSetting />
                   </>
                 ) : (
-                  <Subscribe
-                    my_Id={my_Id}
-                    deleteSubscribe={deleteSubscribe}
-                    followId={followId}
-                    addSubscribe={addSubscribe}
-                    aboutMeFollowing={aboutMeFollowing}
-                  />
+                  <CSubscribe />
                 )}
-            
               </div>
             </Row>
           </section>
@@ -150,65 +121,17 @@ export const PageAboutUser = ({
     </>
   )
 }
-const Subscribe = ({
-  my_Id,
-  deleteSubscribe,
-  aboutMeFollowing = [],
-  addSubscribe,
-  followId,
-}) => {
-  const checkFollowId = aboutMeFollowing?.find(
-    (follower) => follower?._id === followId,
-  )?._id
-
-
-  console.log('FOLLOWING ', checkFollowId)
-
-  return (
-    <>
-      <div style={{ display: 'flex' }}>
-        {checkFollowId ? (
-          <Button
-            size="large" type="primary"
-             danger
-            onClick={() => deleteSubscribe(my_Id, followId)}
-          >
-            Unsubscribe
-          </Button>
-        ) : (
-          <Button
-            size="large"
-              type="primary"
-              primary
-            onClick={() => addSubscribe(my_Id, followId)}
-          >
-            Subscribe
-          </Button>
-        )}
-      </div>
-    </>
-  )
-}
 
 export const CPageAboutUser = connect(
   (state) => ({
     my_Id: state.auth?.payload?.sub?.id,
     aboutUser: state.profilePage?.aboutUser,
-    aboutUserFollowers: state.profilePage?.aboutUser?.followers,
-    aboutUserFollowing: state.profilePage?.aboutUser?.following,
-    followId: state.profilePage?.aboutUser?._id,
-    aboutMeFollowing: state.profileData?.aboutMe?.following,
     countAllPostsUser: state.promise?.countAllPostsUser?.payload,
     allPosts: state.profilePage?.allPosts,
-    onePost: state.promise?.onePost?.payload,
   }),
   {
     onAboutUser: actionFullProfilePageUser,
-    actionRemoveDataUser: actionRemoveDataUser,
-    onLoad: actionUploadFile,
     onPost: actionOnePost,
     onPageData: actionFullProfilePageUser,
-    addSubscribe: actionFullSubscribe,
-    deleteSubscribe: actionFullUnSubscribe,
   },
 )(PageAboutUser)

+ 104 - 0
src/pages/setting/Setting.js

@@ -0,0 +1,104 @@
+import React, { useState, useEffect } from 'react'
+import { CEditAvatar } from '../../components/EditAvatar'
+import { Input } from '../../components/Input'
+import { message, Image, Button } from 'antd'
+import { connect } from 'react-redux'
+import { actionUploadFile, actionSetAvatar, actionUserUpsert, actionUserUpdate } from '../../actions'
+import { Basic, ConstructorModal } from '../../helpers'
+export const EditAccount = ({showModalEdit }) => {
+    return (
+         <Button
+            type="primary" style={{
+              fontWeight: '600',
+              fontSize: '15px',
+              transition: ".3s",
+              boxShadow: "0 5px 15px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22)",
+            }}
+    
+          onClick={showModalEdit}>Edit Setting</Button>
+    )
+  }
+const EditSetting = ({ info, myId, onSaveUserUpsert }) => {
+    const [state, setState] = useState(info)
+    const [isModalVisibleEdit, setIsModalVisibleEdit] = useState(false);
+    // actionChangePassword
+    console.log('all info ', info)
+    const showModalEdit = () => {
+      setIsModalVisibleEdit(true);
+    };
+    const handleCancelEdit = () => {
+      setIsModalVisibleEdit(false)
+    }
+    const onChangeLogin = (event) =>
+      setState({
+        ...state,
+        login: event.target.value,
+      })
+    const onChangeNick = (event) =>
+      setState({
+        ...state,
+        nick: event.target.value,
+      })
+  
+    const saveChange = () => {
+      onSaveUserUpsert(state, myId)
+      && message.success(`Save success changed!`)
+      && setIsModalVisibleEdit(false)
+    }
+
+    return (
+      <div>
+        <EditAccount showModalEdit={showModalEdit}/>
+  
+        <ConstructorModal title={'Edit setting'}
+          isModalVisible={isModalVisibleEdit}
+          setIsModalVisible={setIsModalVisibleEdit}
+          handleCancel={handleCancelEdit}
+        >
+  
+          <CEditAvatar setIsModalVisibleEdit={setIsModalVisibleEdit} />
+  
+          <h2> Edit login </h2>
+          <div style={{ display: 'flex', alignItems: 'center', flexDirection: 'row' }}>
+            <Input
+              state={state?.login || ''}
+              className="Input"
+              onChangeText={onChangeLogin}
+            />
+            <Button size="large" style={{ margin: '10px' }}
+            onClick={saveChange}
+            disabled={state?.login ? false : true}
+  
+              type="primary"> Save login </Button>
+          </div>
+          <h2> Edit nick </h2>
+          <div style={{ display: 'flex', alignItems: 'center', flexDirection: 'row' }}>
+            <Input
+              state={state?.nick || ''}
+              className="Input"
+              onChangeText={onChangeNick}
+            />
+            <Button style={{ margin: '10px' }}
+              disabled={state?.nick ? false : true}
+              onClick={saveChange}
+              size="large"
+              type="primary"
+            >
+              Save nick
+            </Button>
+          </div>
+        
+        </ConstructorModal>
+      </div>
+    )
+  }
+  export const CEditSetting = connect(
+    (state) => ({
+      myId: state?.auth.payload.sub?.id,
+      info: state?.profileData?.aboutMe,
+    }),
+    {
+      onSaveUserUpsert: actionUserUpdate,
+    },
+  )(EditSetting)
+  

+ 1 - 1
src/redux/thunk/index.js

@@ -13,7 +13,7 @@ import {
     actionAuthLogout,
     actionClearPromiseForName
   } from '../../actions'
-import { history } from '../../App'
+import { history } from '../../helpers'
   import{actionClearDataUserType} from '../reducers/profileUserPage/profileUserReducer'
 import { actionProfilePageDataType } from '../reducers/profileData/profileReducer'
 import { actionFullAllGetPosts } from '../../actions'