Browse Source

Add modal window for list of likes + edit post page

LenDoc 2 years ago
parent
commit
71093d9953

+ 1 - 1
public/index.html

@@ -18,7 +18,7 @@
   <body>
     <noscript>You need to enable JavaScript to run this app.</noscript>
     <div id="root"></div>
-    <div id="container" style="padding: 24px"> </div>
+    <!-- <div id="container" style="padding: 24px"> </div> -->
     
   </body>
 </html>

+ 2 - 44
src/App.js

@@ -39,6 +39,7 @@ import { LeftCircleFilled, RightCircleFilled } from '@ant-design/icons'
 import { Input, Select } from 'antd'
 import { PagePost } from './components/Post'
 import { CPostForFeed,Feed } from './components/PostFeed'
+import { CSearch } from './components/Search_Users'
 
 console.log(store.getState())
 store.subscribe(() => console.log(store.getState()))
@@ -121,51 +122,8 @@ const CUserFollowers = connect((state) => ({
   followers: state.promise.aboutMe?.payload?.followers,
 }))(UserFollowers)
 
-const ResultUserFind = ({ userFind }) => (
-  <div>
-    {userFind?.map(({ _id, login, avatar }) => (
-      <Link to={`/profile/${_id}`}>
-        <Avatar
-          style={{
-            width: '20px',
-            height: '20px',
-            marginRight: '30px',
-            position: 'absolute',
-          }}
-          src={'/' + avatar?.url || user}
-        />
 
-        <h3 style={{ marginLeft: '30px' }}> {login}</h3>
-      </Link>
-    ))}
-  </div>
-)
-const SearchUser = ({ onSearch, searchUser }) => {
-  // const [value, setValue]=useState('')
-  const onSearchUser = (value) => onSearch(value)
-  const { Search } = Input
-  return (
-    <>
-      <Popover
-        placement="bottom"
-        content={<ResultUserFind userFind={searchUser} />}
-        trigger="click"
-      >
-        <Search
-          placeholder="input search text"
-          allowClear
-          enterButton="Search"
-          size="large"
-          onSearch={onSearchUser}
-        />
-      </Popover>
-    </>
-  )
-}
-const CSearch = connect(
-  (state) => ({ searchUser: state.promise?.searchUser?.payload }),
-  { onSearch: actionSearchUser },
-)(SearchUser)
+
 const CUserEdit = connect((state) => ({}), {})(PageAboutUser)
 
 const Header = () => {

+ 20 - 6
src/App.scss

@@ -1,7 +1,15 @@
 .App {
   // text-align: center;
+  @font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
+  'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
+  'Noto Color Emoji';
 }
+body{
+  font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
+}
+
 @import '~antd/dist/antd.css';
+
 .Dropzone{
   flex: 1;
   display: flex;
@@ -53,8 +61,8 @@ li {
   list-style-type: none; /* Убираем маркеры */
  }
 main{
-  margin-left:200px;
-  margin-right: 200px;
+  // margin-left:200px;
+  // margin-right: 200px;
 }
 .Title{
   text-align: left;
@@ -100,6 +108,9 @@ main{
   margin: 0 10%;
   border-radius: 5px;
 }
+.Modal{
+  font-size: medium;
+}
 .PostFeed{
   border-width: 20;
   border-color: rgb(138, 138, 220);
@@ -135,12 +146,15 @@ main{
 .Comments{
 
     position: fixed;
-    left: 50%; bottom: 10%; 
-    padding: 10px;
+
     margin:20px;
+    width: 30%;
+  //  left: 50%; bottom: 10%; 
+  padding: 10px;
+   // margin:20px;
    
     // color: #fff; 
-     width: 30%; /* Ширина слоя */
+   //  width: 30%; /* Ширина слоя */
 }
 .active {
   background-color: red;
@@ -152,7 +166,7 @@ main{
   // align-items: center;
   // justify-content: center;
   flex-direction:column;
-  width: 100%;
+  // width: 100%;
   height: 300px;
   // padding: 1em;
   overflow-y: scroll;

+ 26 - 0
src/actions/index.js

@@ -252,6 +252,32 @@ export const actionOnePost = (_id) => async (dispatch) => {
     ),
   )
 }
+
+export const actionFindLikes = (_id) => async (dispatch) => {
+  await dispatch(
+    actionPromise(
+      'onePost',
+      gql(
+        `query OneFind($post:String){
+         PostFindOne(query:$post){
+        likes{
+          _id
+          owner{				
+             _id login avatar {url}
+            }
+      }
+        }
+      }`,
+        {
+          post: JSON.stringify([{ _id },
+            
+          ]),
+        },
+      ),
+    ),
+  )
+}
+
 export const actionAllFollowers = (_id) => async (dispatch) => {
   await dispatch(
     actionPromise(

+ 1 - 1
src/components/DropZone.js

@@ -58,7 +58,7 @@ console.log('STATE PHOTO ', visible)
     <li>
       {/* <img   style={{ maxWidth: '200px', maxHeight: '200px' }} src={ '/' + url} /> */}
           <Image 
-           width={200}
+          //  width={200}
         
            style={{  maxWidth: '200px', maxHeight: '200px' }} src={ '/' + url} 
           //  style={{ display: 'none' }}

+ 86 - 27
src/components/Post.js

@@ -1,6 +1,6 @@
 import { Router, Route, Link, Redirect, Switch } from 'react-router-dom'
 import {
-  actionAllPosts, actionOnePost, addEmoji, actionAddFullComment, actionGetFindLiked, actionFindSubComment,
+  actionAllPosts, actionOnePost, actionFindLikes, actionAddFullComment, actionGetFindLiked, actionFindSubComment,
   actionAddSubFullComment, actionDeleteFullLike, actionAddFullLike, actionAddLike, actionDeleteLike
 } from '../actions'
 import photoNotFound from '../materials/photoNotFound.png'
@@ -9,7 +9,7 @@ import { Carousel,Avatar,Tooltip } from 'antd'
 import user from '../materials/user.png'
 import { Provider, connect } from 'react-redux'
 import { Row, Col } from 'antd';
-import { Divider, Input, Button } from 'antd';
+import { Divider, Input, Button, Modal } from 'antd';
 import { EditOutlined } from '@ant-design/icons'
 import moment from 'moment';
 import {CComments, AddComment} from '../components/Post_Comment'
@@ -134,47 +134,108 @@ export const MyCarousel = ({ images = [] }) => {
     </>
   )
 }
-const Like = ({ my_Id, findLikes, postId, addLike, deleteLike, likes=[] }) =>
+const Likes = ({ likes }) =>
 {
-  const [view, setView] = useState(false);
+  return (
+    <>
+    <div className='Modal'>
+        {
+          likes &&
+          likes?.map(({ owner:{_id, login, avatar} }) => (
+            // <div style={{ display: 'flex', flexDirection:'row' }}>
+          
+                
+            <Link to={`/profile/${_id}`}>
+              <Row>
+              <Col offset={1}>
+            <Avatar
+              style={{
+                width: '50px',
+                height: '50px',
+                // marginRight: '30px',
+                // position: 'absolute',
+              }}
+              src={'/' + avatar?.url || user}
+                  />
+                </Col>
+                <Col offset={2}>
+                    <h3 > {login}</h3>
+                 </Col>
+                 </Row>
+                </Link>
+          ))
+        }
+    </div>
+    </>
+  )
+  }
+const Like = ({ my_Id, postId, addLike, deleteLike, likes=[], children }) =>
+{
+  
+  const [isModalVisible, setIsModalVisible] = useState(false);
+
+  const showModal = () => {
+    setIsModalVisible(true);
+  };
+
+  const handleOk = () => {
+    setIsModalVisible(false);
+  };
+
+  const handleCancel = () => {
+    setIsModalVisible(false);
+  };
   const likeId = likes.find(like => like?.owner?._id === my_Id)?._id
   const changeLike = () => likeId ? deleteLike(likeId, postId) : addLike(postId)
-  console.log('likeId', likeId)
+  // console.log('likeId', likeId)
   return(
     <>
-      
-         <span onClick={changeLike}>
+      <div style={{display:'flex'}}>
+         <h3 onClick={changeLike}>
             {likeId ? 
-            <HeartFilled  style={{ fontSize:'xx-large', color:'red'}} />:
-             <HeartOutlined  style={{ fontSize: 'xx-large' }} /> }
-        </span>
+            <HeartFilled  style={{cursor: 'pointer', fontSize:'xx-large', color:'red'}} />:
+             <HeartOutlined  style={{cursor: 'pointer', fontSize: 'xx-large' }} /> }
+        </h3>
        {likes.length ? 
-         <button style={{ paddingLeft: 8, cursor: 'auto' }} onClick={()=>setView(!view)}> {likes.length} likes
+        <h3 style={{cursor: 'pointer', paddingLeft: 8 }} onClick={showModal}> {likes.length} likes
            
-        </button>
+        </h3>
         :
         '0 likes'}
-       {view}
+      </div>
+      <Modal title="Likes" className="Modal"
+        visible={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
+          <Likes likes={likes}/>
+      </Modal>
     </>
   )
 }
 
-export const PagePost = ({my_Id, onePost,addComment,addCommentReply, addLike, findLikes, findSubComment, deleteLike, aboutMe: { avatar, login } = {}, onPost }) => {
+export const PagePost = ({my_Id, onePost,likes, addComment,addCommentReply, addLike, findSubComment, deleteLike, aboutMe: { avatar, login } = {}, onPost }) => {
 
  console.log('onePost ', onePost)
   return (
     <>
      <Row>
-      <Col span={12}>
+      <Col span={14}>
 {/* <div  style={{display: 'flex'}}> */}
     
       <MyCarousel style={{position: 'absolute'}} images={onePost?.images} />
-      <h3 style={{ textAlign: 'center', padding:'10%'}}>
+      <h3 style={{ textAlign: 'center', padding:'30px'}}>
             Created Post: {new Intl.DateTimeFormat('en-GB').format(onePost?.createdAt)}
-        </h3>
+          </h3>
+          <div style={{marginLeft:'100px'}}>
+          {/* <Col span={3} offset={2}> */}
+          <Like my_Id={my_Id} addLike={addLike} deleteLike={deleteLike} likes={onePost?.likes} postId={onePost?._id}>
+            
+              <Likes likes={onePost?.likes} />
+            
+          </Like>
+              {/* </Col> */}
+           </div>
 {/* </div> */}
     </Col>
-<Col span={12}>
+<Col span={8}>
 <div  style={{display: 'flex', flexDirection:'row'}}>
 
       {avatar ? (
@@ -196,17 +257,14 @@ export const PagePost = ({my_Id, onePost,addComment,addCommentReply, addLike, fi
       <Divider>Comments</Divider>
       <div className="Scroll">
 
-            <CComments comments={onePost?.comments || []}/>
+            <CComments comments={onePost?.comments || []} />
+        
      </div>
-          <Like my_Id={my_Id} findLikes={findLikes} addLike={addLike} deleteLike={deleteLike} likes={onePost?.likes} postId={(onePost?._id)}>
-            {
-              <div>
-          my likes
-              </div>}
-          </Like>
+
        {/* <HeartTwoTone twoToneColor="#eb2f96" /> */}
-          <AddComment addComment={addComment} onePost={onePost}/>
+            <AddComment addComment={addComment} onePost={onePost} />
         </Col>
+     
         </Row>
     </>
   )
@@ -218,11 +276,12 @@ export const CPost = connect((state) => ({
   aboutMe: state.promise?.aboutMe?.payload,
   addComment: state.promise?.addComment?.payload,
   addSubComment: state.promise?.addSubComment,
-
+  
 }), {
   addLike: actionAddFullLike,
   findLikes: actionGetFindLiked,
   deleteLike: actionDeleteFullLike,
   addComment: actionAddFullComment, 
   addCommentReply: actionAddSubFullComment,
+  findLikes:actionFindLikes
 })(PagePost)

+ 7 - 2
src/components/PostFeed.js

@@ -8,6 +8,7 @@ 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 { Row, Col } from 'antd';
 
 const MyPostFeed = ({ postsFeed, onPostsFeed }) => {
     useEffect(() => {
@@ -17,6 +18,9 @@ const MyPostFeed = ({ postsFeed, onPostsFeed }) => {
     return (
       <>
         <h2>Feed</h2>
+        <Row>
+
+        <Col span={12} offset={6}>
             <div>
                 {console.log('POSTFEED', postsFeed)}
           {
@@ -38,8 +42,9 @@ const MyPostFeed = ({ postsFeed, onPostsFeed }) => {
               </div>
             ))
           }
-        </div>
-  
+            </div>
+          </Col>
+    </Row>
         {/* </div> */}
   
         {/* <PagePost onePost={postsFeed}/> <MyCarousel images={postsFeed?.images} />*/}

+ 17 - 27
src/components/Post_Comment.js

@@ -1,5 +1,8 @@
 import { Router, Route, Link, Redirect, Switch } from 'react-router-dom'
-import {actionAllPosts,actionOnePost,actionAddFullComment,actionGetFindLiked, actionFindSubComment,actionAddSubFullComment,actionDeleteFullLike,actionAddFullLike,actionAddLike,actionDeleteLike} from '../actions'
+import {
+  actionAllPosts, actionOnePost, actionAddFullComment, actionGetFindLiked,
+  actionFindSubComment, actionAddSubFullComment, actionDeleteFullLike, actionAddFullLike, actionAddLike, actionDeleteLike
+} from '../actions'
 import photoNotFound from '../materials/photoNotFound.png'
 import { LeftCircleFilled, RightCircleFilled, HeartOutlined,HeartTwoTone,HeartFilled } from '@ant-design/icons'
 import { Carousel,Avatar,Tooltip } from 'antd'
@@ -17,37 +20,22 @@ import { NimblePicker, Emoji } from 'emoji-mart'
 // import InputEmoji from 'react-input-emoji'; 
 import reactStringReplace from 'react-string-replace'
 // const postId="625afa1d069dca48a822ffb0"
-export const AddComment =({addComment, onePost})=>{
+export const AddComment = ({ addComment, onePost }) => {
   const [text, setComment] = useState('')
-  const [showEmojiPicker, setShowEmojiPicker]=useState(false)
+  const [showEmojiPicker, setShowEmojiPicker] = useState(false)
   const addEmoji = ({ colons }) => {
     setComment((text + ' ' + colons).trim());
   };
 
   return (
-
-    // <div style={{ display: 'inline-block' }}>
-
-      <div className="Comments" style={{ display: 'flex',  margin: '0 5px' }}>
+    <>
+      {
+        showEmojiPicker && <Picker autoFocus={true}
+          style={{ color: '#ae65c5', position: 'absolute', bottom: '160px', right: '30px' }}
+          onSelect={emojiTag => addEmoji(emojiTag)} set="apple" />
+      }
       
-           {
-          showEmojiPicker&& <Picker onSelect={emojiTag => addEmoji(emojiTag)}  set="apple" />
-        }
- {/* <Button onClick={<Picker  set="apple" />}   // type="link"
-              // shape="circle"
-              // icon="smile"
-          //onSelect={emojiTag => addEmoji(emojiTag)}
-            > smile </Button>
- */}
-           {/* <InputEmoji style={{ display: 'inline-block' }}
-          value={text}
-          onChange={setComment}
-          cleanOnEnter
-          onEnter={()=>addComment(postId, text)}
-          placeholder="Type a message"
-        />   */}
-        
-
+      <div className="" style={{ display: 'flex',  margin: '100px 10px' }}>
          <Input style={{ display: 'inline-block' }} size="large" placeholder='Add a comment...' 
           value={text} onChange={e => { setComment(e.target.value) }}
         onPressEnter={e => { setComment(e.target.value) }}/> 
@@ -63,8 +51,10 @@ export const AddComment =({addComment, onePost})=>{
         
         </SmileOutlined>
        
-     </div>
+        </div>
+        </>
     )
+      
 }
 const SpoilerButton = ({text, close, children }) => {
     const [opened, setOpened] = useState(close)
@@ -123,7 +113,7 @@ const CommentForReply =({addCommentReply, commentId, onePost})=>{
       <div style={{width:'90%',display:'inline-block', background:'#c8c8c8'}}>
    <EditOutlined style={{float:'right',  fontSize: 'x-large' }}/>
         <h3 style={{display:'block'}}>  {reactStringReplace(text, /:(.+?):/g, (match, i) => (
-          <Emoji emoji={match} set='apple' size={20}/> ))}
+          <Emoji emoji={match}  set='apple' size={20}/> ))}
         </h3>
        
       </div>

+ 62 - 0
src/components/Search_Users.js

@@ -0,0 +1,62 @@
+import { Link } from 'react-router-dom'
+import { connect } from 'react-redux'
+import { Avatar, Input } from 'antd'
+import { Carousel, Popover } from 'antd'
+import user from '../materials/user.png'
+
+import {
+    actionAboutMe,
+    actionAllPostsFeed,
+    actionAllPosts,
+    actionSetAvatar,
+    actionPostsFeed,
+    actionAllFollowing,
+    actionAllFollowers,
+    actionPostsMyFollowing2,
+    actionSearchUser,
+  } from '../actions'
+export const ResultUserFind = ({ userFind }) => (
+    <div>
+      {userFind?.map(({ _id, login, avatar }) => (
+        <Link to={`/profile/${_id}`}>
+          <Avatar
+            style={{
+              width: '20px',
+              height: '20px',
+              marginRight: '30px',
+              position: 'absolute',
+            }}
+            src={'/' + avatar?.url || user}
+          />
+  
+          <h3 style={{ marginLeft: '30px' }}> {login}</h3>
+        </Link>
+      ))}
+    </div>
+)
+ const SearchUser = ({ onSearch, searchUser }) => {
+    // const [value, setValue]=useState('')
+    const onSearchUser = (value) => onSearch(value)
+    const { Search } = Input
+    return (
+      <>
+        <Popover
+          placement="bottom"
+          content={<ResultUserFind userFind={searchUser} />}
+          trigger="click"
+        >
+          <Search
+            placeholder="input search text"
+            allowClear
+            enterButton="Search"
+            size="large"
+            onSearch={onSearchUser}
+          />
+        </Popover>
+      </>
+    )
+  }
+ export const CSearch = connect(
+    (state) => ({ searchUser: state.promise?.searchUser?.payload }),
+    { onSearch: actionSearchUser },
+  )(SearchUser)

+ 19 - 6
src/components/User.js

@@ -13,6 +13,7 @@ import { store } from '../reducers'
 import { useDropzone } from 'react-dropzone'
 import { Upload, Button, DatePicker, Space } from 'antd'
 import { UploadOutlined, SearchOutlined } from '@ant-design/icons'
+import { Row, Col } from 'antd';
 
 export function Basic({ onLoad }) {
   const { acceptedFiles, getRootProps, getInputProps } = useDropzone()
@@ -123,9 +124,13 @@ export const PageAboutUser = ({
     // "62361ebb92c08631bc4b0e96")
   }, [])
   return (
+  
+    <>
+      <Row>
+      <Col span={12} offset={6}>
     <section className="AboutMe">
       <Avatar
-        style={{ marginRight: '20px', width: '170px', height: '150px' }}
+        style={{ marginRight: '20px', width: '150px', height: '150px' }}
         src={'/' + avatar?.url || user}
       />
       <div className="Info">
@@ -162,7 +167,14 @@ export const PageAboutUser = ({
             <p>Edit avatar</p>
             <CEditInfo />
           </div>
-        </EditAccount>
+                </EditAccount>
+                 </div>
+        </section>
+            
+        </Col>
+      </Row>
+      <Row>
+      <Col span={16} offset={6}>
         <div
           style={{
             display: 'flex',
@@ -174,10 +186,11 @@ export const PageAboutUser = ({
           {(allPosts || [])?.map((item) => (
             <Card post={item} onPost={onPost} />
           ))}
-        </div>
-    
-      </div>
-    </section>
+          </div>
+        </Col>
+        </Row>
+    </>
+     
   )
 }
 export const CPageAboutUser = connect(