Pārlūkot izejas kodu

fix bags, remove modal navigation my profile

makstravm 2 gadi atpakaļ
vecāks
revīzija
aaa9283309

+ 0 - 1
README.md

@@ -1,6 +1,5 @@
 # Getting Started with Create React App
 
-This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
 
 ## Available Scripts
 

+ 3 - 4
src/App.js

@@ -12,7 +12,7 @@ import { CRRoute } from './helpers';
 import { CPostPage } from './pages/PostPage';
 import { CAllPosts } from './pages/AllPosts';
 import { CEntityEditorPost } from './pages/EntityEditorPost';
-import { SettingsPage } from './pages/SettingsPage';
+import { CSettingsPage } from './pages/SettingsPage';
 import { Authorization } from './pages/Authorization';
 import { CCollectionPage } from './pages/CollectionPage';
 import { useMediaQuery } from 'react-responsive';
@@ -42,9 +42,8 @@ const AppContent = ({ isToken }) => {
                         <Route path='/feed' component={CMainPostsFeed} />
                         <Route path='/profile/:_id' component={CProfilePage} />
                         {/* <Route path='/message' component={Aside} /> */}
-                        <Route path='/edit/post/new' component={CEntityEditorPost} exact />
                         <Route path='/edit/post/:_id' component={CEntityEditorPost} />
-                        <Route path='/my-settings' component={SettingsPage} />
+                        <Route path='/my-settings' component={CSettingsPage} />
                         <Route path='/all' component={CAllPosts} />
                         <Route path='/my-collection' component={CCollectionPage} />
                         <CRRoute path='/post/:id' component={CPostPage} />
@@ -52,11 +51,11 @@ const AppContent = ({ isToken }) => {
                     </Switch>
                 </Main>
                 {isTabletDevice && <FooterComponent />}
-
             </Content >
         }
     </Router >
 }
+
 const CAppContent = connect(state => ({ isToken: state.auth?.token }))(AppContent)
 store.subscribe(() => console.log(store.getState()))
 

+ 38 - 99
src/App.scss

@@ -1,53 +1,3 @@
-//     RESET STYLE
-html {
-    box-sizing: border-box;
-}
-
-*,
-*::after,
-*::before {
-    box-sizing: inherit;
-}
-
-ul[class],
-ol[class] {
-    padding: 0;
-}
-
-body,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6,
-p,
-ul[class],
-ol[class],
-li,
-figure,
-figcaption,
-blockquote,
-dl,
-dd {
-    margin: 0;
-}
-
-ul[class] {
-    list-style: none;
-}
-
-img {
-    max-width: 100%;
-    display: block;
-}
-
-input,
-button,
-textarea,
-select {
-    font: inherit;
-}
 $defaultColorW: #fff;
 $defaultColorB: #000;
 
@@ -62,8 +12,8 @@ video {
     max-height: 500px;
 }
 .Header {
-    display: flex;
     background-color: #ececec;
+    display: flex;
     justify-content: space-between;
     align-items: center;
     .Logo {
@@ -109,6 +59,9 @@ video {
             &.active {
                 svg {
                     fill: $defaultColorB;
+                    polygon {
+                        stroke: $defaultColorB;
+                    }
                 }
             }
         }
@@ -147,38 +100,6 @@ video {
     }
 }
 
-.dropMenu {
-    max-width: 200px;
-    min-width: 150px;
-    .anticon.anticon-user,
-    li {
-        transition: all 0.3s;
-        &:hover {
-            background-color: rgba($color: #0057ff, $alpha: 0.12);
-        }
-    }
-    a {
-        transition: all 0.3s;
-    }
-    &__icon {
-        margin-right: 2px;
-        svg {
-            width: 15px;
-            height: 15px;
-        }
-    }
-    button {
-        cursor: pointer;
-        text-align-last: left;
-        width: 100%;
-        background-color: transparent;
-        border: none;
-        padding: 0;
-        margin: 0;
-        transition: all 0.3s;
-    }
-}
-
 .Authorization {
     height: 100%;
     background-position: right top;
@@ -210,12 +131,17 @@ video {
 
 .ant-layout-header,
 .ant-layout-footer {
-    height: 58px;
-    line-height: 58px;
-    padding: 0 20px;
+    height: 60px;
     background-color: $defaultColorW;
     box-shadow: 0 0 9px 5px rgba($color: #001529, $alpha: 0.4);
 }
+.ant-layout-header {
+    padding-left: 20px;
+    padding-right: 20px;
+}
+.ant-layout-footer {
+    padding: 10px 20px;
+}
 
 .Main {
     position: relative;
@@ -239,7 +165,6 @@ video {
         object-fit: contain;
     }
     &__dots.slick-dots {
-        bottom: -14px;
         z-index: 1;
         li {
             border-radius: 50%;
@@ -247,6 +172,7 @@ video {
             width: 10px;
             height: 10px;
             overflow: hidden;
+            border: 1px solid #000;
             &.slick-active {
                 border-radius: 5px;
                 width: 20px;
@@ -656,7 +582,7 @@ video {
 }
 .avatar-uploader {
     display: flex;
-justify-content: center;
+    justify-content: center;
     bottom: 10px;
 
     .ant-upload {
@@ -712,33 +638,42 @@ justify-content: center;
         }
     }
 }
+.Exit-box__btn {
+    button {
+        display: block;
+        margin-left: auto;
+    }
+}
 
 @media (max-width: 800px) {
     .PostOne {
         padding-top: 30px;
         &__inner {
-            display: block;
+            display: grid;
             grid-template-columns: 1fr;
             grid-template-rows: (45px, 1fr, 1fr);
             max-height: 100%;
         }
         &__title {
+            grid-area: 1 / 1 / 2 / 2;
         }
         &__image {
+            grid-area: 2 / 1 / 3 / 2;
             width: 100%;
+            img,
+            video {
+                height: auto;
+            }
         }
         &__description {
+            grid-area: 3 / 1 / 4 / 2;
         }
-        &__image img,
-        video {
-            height: auto;
-        }
-    }
-    .Profile {
-        &__box {
-            img,
-            video {
-                max-height: 120px;
+        .Profile {
+            &__box {
+                img,
+                video {
+                    max-height: 120px;
+                }
             }
         }
     }
@@ -750,6 +685,10 @@ justify-content: center;
             width: 35vw;
         }
     }
+    .Main {
+        padding-left: 10px;
+        padding-right: 5px;
+    }
     .ant-input-affix-wrapper {
         width: 45vw;
         padding: 2px 5px 2px 7px;

+ 2 - 2
src/components/Footer.jsx

@@ -1,11 +1,11 @@
 import { Footer } from 'antd/lib/layout/layout';
 import React from 'react';
-import { UserNav } from './header/Header';
+import { CUserNavIcon } from './header/Header';
 
 export const FooterComponent = () => {
     return (
         <Footer style={{ position: 'fixed', zIndex: 3, width: '100%', bottom: 0 }}>
-            <UserNav />
+            <CUserNavIcon />
         </Footer>
     )
 };

+ 5 - 73
src/components/FormAuthorization.jsx

@@ -7,10 +7,10 @@ import { actionFullLogIn, actionFullRegister } from '../actions';
 const FormAuthorization = ({ buttonTitle, onSignIn, loginChek }) => {
     const [loading, setLoading] = useState(false);
     useEffect(() => {
-        if (loginChek.status === "PENDING") {
+        if (loginChek?.status === "PENDING") {
             setLoading(loading => loading = true)
         }
-        if (loginChek.status === "RESOLVED" && loginChek.payload === null) {
+        if (loginChek?.status === "RESOLVED" && loginChek?.payload === null) {
             message.error({
                 content: 'Wrong login or password',
                 className: 'custom-class',
@@ -20,7 +20,7 @@ const FormAuthorization = ({ buttonTitle, onSignIn, loginChek }) => {
             })
             setLoading(loading => loading = false)
         }
-    }, [loginChek.status]);
+    }, [loginChek?.status]);
 
 
     const onFinish = ({ login, password, remember }) => {
@@ -81,75 +81,7 @@ const FormAuthorization = ({ buttonTitle, onSignIn, loginChek }) => {
         </Form>
     )
 }
-export const CLoginForm = connect(state => ({ loginChek: state?.promise?.login || {} }), { onSignIn: actionFullLogIn, })(FormAuthorization)
-export const CRegisterForm = connect(state => ({ status: state?.promise?.login }), { onSignIn: actionFullRegister, })(FormAuthorization)
-
-
-
-
-// import { Button, Space } from 'antd';
-// import { PoweroffOutlined } from '@ant-design/icons';
 
-// class App extends React.Component {
-//     state = {
-//         loadings: [],
-//     };
-
-//     enterLoading = index => {
-//         this.setState(({ loadings }) => {
-//             const newLoadings = [...loadings];
-//             newLoadings[index] = true;
-
-//             return {
-//                 loadings: newLoadings,
-//             };
-//         });
-//         setTimeout(() => {
-//             this.setState(({ loadings }) => {
-//                 const newLoadings = [...loadings];
-//                 newLoadings[index] = false;
-
-//                 return {
-//                     loadings: newLoadings,
-//                 };
-//             });
-//         }, 6000);
-//     };
-
-//     render() {
-//         const { loadings } = this.state;
-//         return (
-//             <>
-//                 <Space style={{ width: '100%' }}>
-//                     <Button type="primary" loading>
-//                         Loading
-//                     </Button>
-//                     <Button type="primary" size="small" loading>
-//                         Loading
-//                     </Button>
-//                     <Button type="primary" icon={<PoweroffOutlined />} loading />
-//                 </Space>
+export const CLoginForm = connect(state => ({ loginChek: state?.promise?.login || {} }), { onSignIn: actionFullLogIn, })(FormAuthorization)
 
-//                 <Space style={{ width: '100%' }}>
-//                     <Button type="primary" loading={loadings[0]} onClick={() => this.enterLoading(0)}>
-//                         Click me!
-//                     </Button>
-//                     <Button
-//                         type="primary"
-//                         icon={<PoweroffOutlined />}
-//                         loading={loadings[1]}
-//                         onClick={() => this.enterLoading(1)}
-//                     >
-//                         Click me!
-//                     </Button>
-//                     <Button
-//                         type="primary"
-//                         icon={<PoweroffOutlined />}
-//                         loading={loadings[2]}
-//                         onClick={() => this.enterLoading(2)}
-//                     />
-//                 </Space>
-//             </>
-//         );
-//     }
-// }
+export const CRegisterForm = connect(state => ({ status: state?.promise?.login }), { onSignIn: actionFullRegister, })(FormAuthorization)

+ 24 - 48
src/components/header/Header.jsx

@@ -3,41 +3,12 @@ import logo from '../../logo.svg';
 import { Link, NavLink } from 'react-router-dom';
 import { CFieldSearch } from './Search';
 import { connect } from 'react-redux';
-import { actionAuthLogout, actionRemoveMyDataAC } from '../../actions';
 import { Header } from 'antd/lib/layout/layout';
-import { Col, Menu, Popover, Row } from 'antd';
-import { UserOutlined, CompassOutlined, SettingOutlined, HomeOutlined, ImportOutlined, MessageOutlined, PlusCircleOutlined } from '@ant-design/icons/lib/icons';
+import { Col, Row } from 'antd';
+import { CompassOutlined, HomeOutlined, MessageOutlined, PlusCircleOutlined } from '@ant-design/icons/lib/icons';
 import { UserAvatar } from './UserAvatar';
-import { CollectionEmptySvg } from '../../helpers';
 import MediaQuery from "react-responsive";
-
-
-export const UserNav = () =>
-    <div className='UserNav'>
-        <CUserNavIcon />
-    </div>
-
-const ProfileDropMenu = ({ myID, onLogOut, removeMydata }) =>
-    <Menu className='dropMenu'>
-        <Menu.Item key={'0'}>
-            <Link to={`/profile/${myID}`}><UserOutlined /> My Profile</Link>
-        </Menu.Item>
-        <Menu.Item key={'1'}>
-            <Link to={'/my-collection'}>< CollectionEmptySvg className='dropMenu__icon' />Collection</Link>
-        </Menu.Item>
-        <Menu.Item key={'2'}>
-            <Link to={'/my-settings'}><SettingOutlined /> Settings</Link>
-        </Menu.Item>
-        <Menu.Divider />
-        <Menu.Item key={'3'}>
-            <button onClick={() => {
-                onLogOut()
-                removeMydata()
-            }}><ImportOutlined /> Log out</button>
-        </Menu.Item>
-    </Menu>
-
-const CProfileDropMenu = connect(null, { onLogOut: actionAuthLogout, removeMydata: actionRemoveMyDataAC })(ProfileDropMenu)
+import { CollectionEmptySvg } from '../../helpers';
 
 
 const UserNavIcon = ({ userData: { _id, avatar, login } }) =>
@@ -54,21 +25,26 @@ const UserNavIcon = ({ userData: { _id, avatar, login } }) =>
         <Col >
             <NavLink to='/all'><CompassOutlined /></NavLink>
         </Col>
-        <Col>
-            <MediaQuery minWidth={768}>
-                <Popover placement="bottomRight" content={<CProfileDropMenu myID={_id} />}>
+        <Col >
+            <NavLink to='/my-collection'><CollectionEmptySvg /></NavLink>
+        </Col>
+        <MediaQuery minWidth={787}>
+            <Col>
+                <Link to={`/profile/${_id}`}>
                     <UserAvatar avatar={avatar} login={login} avatarSize={'45px'} />
-                </Popover>
-            </MediaQuery>
-            <MediaQuery maxWidth={768}>
-                <Popover placement="topRight"  content={<CProfileDropMenu myID={_id} />}>
+                </Link>
+            </Col>
+        </MediaQuery>
+        <MediaQuery maxWidth={786}>
+            <Col>
+                <Link to={`/profile/${_id}`}>
                     <UserAvatar avatar={avatar} login={login} avatarSize={'45px'} />
-                </Popover>
-            </MediaQuery>
-        </Col>
+                </Link>
+            </Col>
+        </MediaQuery>
     </Row >
 
-const CUserNavIcon = connect(state => ({ userData: state.myData || {} }))(UserNavIcon)
+export const CUserNavIcon = connect(state => ({ userData: state.myData || {} }))(UserNavIcon)
 
 
 const Logo = () =>
@@ -80,15 +56,15 @@ const Logo = () =>
 const HeaderComponent = () =>
     <Header style={{ position: 'fixed', zIndex: 3, width: '100%' }}>
         <Row justify="space-between" align="middle" className='Header__inner'>
-            <Col >
+            <Col flex={2}>
                 <Logo />
             </Col>
-            <Col >
+            <Col flex={1}>
                 <CFieldSearch />
             </Col>
-            <MediaQuery minWidth={768}>
-                <Col >
-                    <UserNav />
+            <MediaQuery minWidth={787}>
+                <Col flex={2}>
+                    <CUserNavIcon />
                 </Col>
             </MediaQuery>
         </Row>

+ 10 - 14
src/components/header/UserAvatar.js

@@ -2,17 +2,13 @@ import Avatar from "antd/lib/avatar/avatar"
 import { backURL } from "../../helpers"
 import noAva from "../../images/noAva.png"
 
-export const UserAvatar = ({ avatarSize, avatar }) => {
-    return (
-        <>
-            <Avatar style={{
-                width: avatarSize,
-                height: avatarSize
-            }}
-                src={avatar && avatar?.url
-                    ? <img src={(backURL + '/' + avatar.url)} alt='avatar' />
-                    : <img src={noAva} alt="avatar"/>
-                } />
-        </>
-    )
-}
+export const UserAvatar = ({ avatarSize, avatar }) =>
+    <Avatar style={{
+        width: avatarSize,
+        height: avatarSize
+    }}
+        src={avatar && avatar?.url
+            ? <img src={(backURL + '/' + avatar.url)} alt='avatar' />
+            : <img src={noAva} alt="avatar" />
+        } />
+

+ 1 - 1
src/pages/AllPosts.jsx

@@ -24,7 +24,7 @@ const AllPosts = ({ onAllPosts, postsRemove }) => {
     }, [])
 
     const scrollHandler = (e) => {
-        if (e.target.documentElement.scrollHeight - (e.target.documentElement.scrollTop + window.innerHeight) < 500) {
+        if (e.target.documentElement.scrollHeight - (e.target.documentElement.scrollTop + window.innerHeight) < 300) {
             setCheckScroll(true)
         }
     }

+ 2 - 17
src/pages/CollectionPage.jsx

@@ -8,34 +8,19 @@ import { Container } from './Content';
 import { CPreloader } from './Preloader';
 
 export const CollectionPage = ({ onLoadPosts, postsRemove }) => {
-    const [checkScroll, setCheckScroll] = useState(true)
 
     useEffect(() => {
-        if (checkScroll) {
-            onLoadPosts()
-            setCheckScroll(false)
-        }
-    }, [checkScroll])
-
-    useEffect(() => {
-        document.addEventListener('scroll', scrollHandler)
+        onLoadPosts()
         return () => {
-            document.removeEventListener('scroll', scrollHandler)
             postsRemove()
         }
     }, [])
 
-    const scrollHandler = (e) => {
-        if (e.target.documentElement.scrollHeight - (e.target.documentElement.scrollTop + window.innerHeight) < 500) {
-            setCheckScroll(true)
-        }
-    }
-
     return (
         <Container>
             <CPreloader promiseName='onLoadMyCollections' />
             <Divider><Title level={1}>Collections</Title></Divider>
-            <CPosts /> 
+            <CPosts />
         </Container>
     )
 }

+ 13 - 11
src/pages/EntityEditorPost.jsx

@@ -13,26 +13,28 @@ import { history } from '../App'
 const ContainEditorPost = ({ children }) =>
     <div className='ContainEditPost ContainerInner'>{children}</div>
 
-const EntityEditorPost = ({ match: { params: { _id } }, myID, entity, status, onSave, updatePost, clearState}) => {
+const EntityEditorPost = ({ match: { params: { _id } }, myID, entity, status, onSave, updatePost, clearState }) => {
 
     const [photos, setPhotos] = useState(entity?.images || []);
     const [titleSend, setTitleSend] = useState(entity?.title || '')
     const [description, setDescription] = useState(entity?.text || '');
 
-
     useEffect(() => {
         if (_id !== 'new') {
-            let newEntity
             if (Array.isArray(entity)) {
-                newEntity = entity.find(e => e._id === _id)
-                setPhotos(newEntity?.images || [])
-                setTitleSend(newEntity?.title || '')
-                setDescription(newEntity?.text || '')
-            } else if (!Object.keys(entity = {}).length) history.push('/edit/post/new')
-            updatePost(newEntity)
-            return () => {
-                clearState()
+                let findEntity = entity.find(e => e._id === _id)
+                setPhotos(findEntity?.images)
+                setTitleSend(findEntity?.title)
+                setDescription(findEntity?.text)
+                updatePost(findEntity)
             }
+        } else {
+            setPhotos([])
+            setTitleSend('')
+            setDescription('')
+        }
+        return () => {
+            clearState()
         }
     }, []);
 

+ 1 - 1
src/pages/Preloader.jsx

@@ -2,9 +2,9 @@ import { message, Spin } from 'antd'
 import { connect } from 'react-redux'
 import preloader from '../images/preloader.gif'
 
-<Spin size="large" />
 const PreloaderImg = () =>
     <div className='PreloaderImg'>
+{/* <Spin size="large" /> */}
         <img src={preloader} alt="preloader" />
     </div>
 

+ 1 - 1
src/pages/ProfilePage.jsx

@@ -107,7 +107,7 @@ const ProfilePage = ({ match: { params: { _id } }, getProfileUser, clearDataProf
     }, [_id, checkScroll])
 
     const scrollHandler = (e) => {
-        if (e.target.documentElement.scrollHeight - (e.target.documentElement.scrollTop + window.innerHeight) < 500) {
+        if (e.target.documentElement.scrollHeight - (e.target.documentElement.scrollTop + window.innerHeight) < 300) {
             setCheckScroll(true)
         }
     }

+ 14 - 5
src/pages/SettingsPage.jsx

@@ -1,12 +1,12 @@
 import React, { useEffect, useState } from 'react';
 import { Container } from './Content';
 import { CEditAvatar } from '../components/main/profilePage/EditAvatar'
-import { Button, Col, Divider, Input, message, Row } from 'antd'
+import { Button, Col, Divider, Input, message, Row, Space } from 'antd'
 import Title from 'antd/lib/typography/Title';
 import { connect } from 'react-redux';
-import { EditOutlined } from '@ant-design/icons';
+import { EditOutlined, LogoutOutlined } from '@ant-design/icons';
 import Text from 'antd/lib/typography/Text';
-import { actionFullAboutMeUpsert } from '../actions';
+import { actionAuthLogout, actionFullAboutMeUpsert, actionRemoveMyDataAC } from '../actions';
 
 
 const ContainerSettingsPage = ({ children }) =>
@@ -107,7 +107,11 @@ const EditMyData = ({ myData, status, onUpsert }) => {
 
 const CEditMyData = connect(state => ({ myData: state?.myData, status: state?.promise?.upsertAboutMe?.status }), { onUpsert: actionFullAboutMeUpsert })(EditMyData)
 
-export const SettingsPage = () => {
+const SettingsPage = ({ onLogOut, removeMydata }) => {
+    const handlerExitBtn = () => {
+        onLogOut()
+        removeMydata()
+    }
     return (
         <Container>
             <ContainerSettingsPage>
@@ -120,7 +124,12 @@ export const SettingsPage = () => {
                         <CEditMyData />
                     </Col>
                 </Row>
+                <Space className='Exit-box__btn'>
+                    <Button onClick={handlerExitBtn}><LogoutOutlined /> Exit</Button>
+                </Space>
             </ContainerSettingsPage>
         </Container>
     )
-};
+}
+
+export const CSettingsPage = connect(null, { onLogOut: actionAuthLogout, removeMydata: actionRemoveMyDataAC })(SettingsPage)

+ 2 - 5
src/redux/saga/index.js

@@ -19,7 +19,6 @@ function* promiseWorker({ name, promise }) {
     }
 }
 
-
 function* promiseWatcher() {
     yield takeEvery('PROMISE_START', promiseWorker)
 }
@@ -42,6 +41,7 @@ function* routeWatcher() {
     yield takeEvery('ROUTE', routeWorker)
 }
 
+
 //*************** AUTHORIZATION ******************//
 
 
@@ -89,7 +89,6 @@ function* aboutMeUpsertWorker({ nick, login }) {
     }
 }
 
-
 function* aboutMeWatcher() {
     yield all([
         takeEvery('ABOUT_ME', aboutMeWorker),
@@ -119,6 +118,7 @@ function* postsFeedWorker() {
         }
     }
 }
+
 function* allPostsFeedWorker() {
     const {
         postsFeed: { posts, count }
@@ -127,16 +127,13 @@ function* allPostsFeedWorker() {
     if (posts?.length !== (count ? count : 1)) {
         const taskPosts = yield fork(promiseWorker, actionGetAllPosts(posts?.length))
         const taskCount = yield fork(promiseWorker, actionAllPostsCount())
-
         const [postsResult, countResult] = yield join([taskPosts, taskCount])
-
         if (postsResult && countResult) {
             yield put(actionAddPostsFeedAC(postsResult, countResult))
         }
     }
 }
 
-
 function* postsFeedWatcher() {
     yield all([
         takeLeading('POSTS_FEED', postsFeedWorker),