Browse Source

16.03.2023 02:10

Volddemar4ik 1 year ago
parent
commit
e9c16a8ed5

+ 4 - 13
js/Project/project/src/App.js

@@ -12,7 +12,8 @@ import { CFeed } from './components/feed';
 import { CComments } from './components/post';
 import { CreatePost } from './components/create_post';
 import Authorization from './components/auth_reg';
-import Header from './components/structure/header';
+// import Header from './components/structure/header';
+import { CHeader } from './components/structure/header';
 import Footer from './components/structure/footer';
 
 // url проекта
@@ -21,21 +22,11 @@ export const url = 'http://hipstagram.node.ed.asmer.org.ua/graphql'
 
 const history = createHistory()
 
-// const Autorization = () =>
-//     <div>
-//         Авторизация
-//     </div>
-
 const Registration = () =>
     <div>
         Регистрация
     </div>
 
-const PageAbout = () =>
-    <div>
-        Страница "О нас"
-    </div>
-
 const Page404 = () =>
     <div>
         NOT FOUND
@@ -47,11 +38,11 @@ function App() {
         <Provider store={store}>
             <Router history={history}>
                 <div className="wrapper">
-                    <Header />
+                    {/* <Header /> */}
+                    <CHeader />
                     <main style={{ flexGrow: '1' }}>
                         <Switch>
                             <Route path="/" component={CFeed} exact />
-                            {/* <Route path="/feed" component={CFeed} /> */}
                             <Route path="/authorization" component={Authorization} />
                             <Route path="/registration" component={Registration} />
                             <Route path="/post/:postId" component={CComments} />

+ 0 - 1
js/Project/project/src/components/auth_reg/index.js

@@ -112,7 +112,6 @@ export default function Authorization() {
                 </Typography>
 
                 <Box
-                    // className='testtt'
                     sx={{
                         display: 'grid',
                         alignSelf: 'start'

+ 11 - 15
js/Project/project/src/components/feed/aboutMe.js

@@ -1,16 +1,12 @@
 import { Avatar, Typography, Box, Stack, CardHeader } from '@mui/material'
-import { useSelector } from 'react-redux'
+import { useSelector, connect } from 'react-redux'
 
 import { url } from "../../App"
 
-
-function AboutMe({ me }) {
+function AboutMe({ aboutMe = {} }) {
 
     const myPostsCount = useSelector(state => state?.promise?.MyPosts?.payload)
 
-    // урл аватара
-    const urlAvatar = url.slice(0, -7) + me?.avatar?.url
-
     return (
         <Box sx={{
             maxWidth: 400
@@ -19,14 +15,14 @@ function AboutMe({ me }) {
                 avatar={
                     <Avatar
                         sx={{ width: 50, height: 50 }}
-                        alt={me?.login}
-                        src={urlAvatar}
+                        alt={aboutMe?.login}
+                        src={url.slice(0, -7) + aboutMe?.avatar?.url}
                     />
                 }
 
                 subheader={
                     <Typography variant='h6'>
-                        {me?.login}
+                        {aboutMe?.login}
                     </Typography>
                 }
             />
@@ -38,18 +34,18 @@ function AboutMe({ me }) {
                     {myPostsCount?.length || '0'} публикаций
                 </Typography>
                 <Typography>
-                    {me?.followers?.length || '0'} подписчиков
+                    {aboutMe?.followers?.length || '0'} подписчиков
                 </Typography>
                 <Typography>
-                    {me?.following?.length || '0'} подписок
+                    {aboutMe?.following?.length || '0'} подписок
                 </Typography>
             </Stack>
+
+            {/* вот тут можно добавить список всех юзеров, которые есть в базе: аватар+логин+кнопка подписаться/отписаться */}
+
         </Box>
 
     )
 }
 
-export default AboutMe
-
-
-
+export const CAboutMe = connect(state => ({ aboutMe: state?.promise?.AboutMe?.payload }))(AboutMe)

+ 1 - 2
js/Project/project/src/components/feed/card_feed.js

@@ -43,7 +43,6 @@ export function CardFeed({ postData }) {
                     </Link>
                 }
 
-                // дата создания поста
                 subheader={dateOfPostParse}
             />
 
@@ -95,7 +94,7 @@ export function CardFeed({ postData }) {
                                 sx={{
                                     order: { xs: 1, sm: 2 }
                                 }}>
-                                {/* Это иконка добавления в избранное - нужно ли */}
+                                {/* Это иконка добавления в избранное - нужно ли? */}
                                 <IconButton>
                                     <TurnedInNot />
                                 </IconButton>

+ 11 - 11
js/Project/project/src/components/feed/index.js

@@ -1,6 +1,6 @@
 import * as React from 'react';
-import { connect, useDispatch } from 'react-redux';
-import { store } from '../redux';
+import { useEffect } from 'react';
+import { connect } from 'react-redux';
 
 import { Box, Paper } from '@mui/material';
 import { styled } from '@mui/material/styles';
@@ -9,8 +9,8 @@ import Grid2 from '@mui/material/Unstable_Grid2/Grid2';
 
 import { actionAboutMe } from '../redux/action';
 import { CardFeed } from './card_feed';
-import AboutMe from './aboutMe';
-import { useEffect } from 'react';
+import { CAboutMe } from './aboutMe';
+
 
 // сам item для поста
 const Item = styled(Paper)(() => ({
@@ -21,8 +21,7 @@ const Item = styled(Paper)(() => ({
 }))
 
 // function Feed({ feed, me = {} }) { // это первый вариант без useEffetc, а просто с store.dispatch
-function Feed({ feed, me = {}, loadFeed }) {
-    // console.log('feed: ', feed)
+function Feed({ feed, loadFeed }) {
 
     useEffect(() => { loadFeed() }, []) // это второй вариант через useEffect
 
@@ -42,7 +41,7 @@ function Feed({ feed, me = {}, loadFeed }) {
                         <Item sx={{
                             position: 'fixed'
                         }}>
-                            <CMe me={me} />
+                            <CAboutMe />
                         </Item>
                     </Grid2>
                 </Grid2>
@@ -51,13 +50,14 @@ function Feed({ feed, me = {}, loadFeed }) {
     )
 }
 
+export const CFeed = connect(state => ({ feed: state.promise?.MyFeed?.payload }), { loadFeed: actionAboutMe })(Feed)
+
 
-// store.dispatch(actionAboutMe())
 
-const CMe = connect(state => ({ me: state?.promise?.AboutMe?.payload }))(AboutMe)
-// export const CFeed = connect(state => ({ feed: state.promise?.MyFeed?.payload }))(Feed)
-export const CFeed = connect(state => ({ feed: state.promise?.MyFeed?.payload }), { loadFeed: actionAboutMe })(Feed) // и это тоже удалить
+// store.dispatch(actionAboutMe()) // это первый вариант без useEffetc, а просто с store.dispatch
+// export const CFeed = connect(state => ({ feed: state.promise?.MyFeed?.payload }))(Feed) // это первый вариант без useEffetc, а просто с store.dispatch
 
+// const CMe = connect(state => ({ me: state?.promise?.AboutMe?.payload }))(AboutMe) // это первый вариант когда все здесь находится
 
 
 

+ 12 - 4
js/Project/project/src/components/redux/action.js

@@ -194,7 +194,18 @@ export const actionFullLogin = (login, password) =>
     }
   }
 
-// =============================
+
+// Thunk разлогина и последующей полной очистки localStorage
+export const actionFullLogout = () =>
+  async dispatch => {
+    // чистим полностью localStorage
+    await dispatch(actionAuthLogout())
+
+    // и перебрасываем пользователя на страницу авторизации
+    window.location.replace('/authorization')
+  }
+
+
 // Thunk для страницы юзера (диспатчим запрос на юзера и на ленту его постов)
 export const actionFullUserFindOne = (id) =>
   async dispatch => {
@@ -202,8 +213,6 @@ export const actionFullUserFindOne = (id) =>
     console.log('test: ', test)
     dispatch(actionFeedFindOne([id], -1, 'UserFeed'))
   }
-// ==============================
-
 
 
 // запрос AboutMe для главной страницы (лента моих постов и мои данные)
@@ -233,7 +242,6 @@ function fileUpload(file) {
   const formData = new FormData()
   formData.append('photo', file)
 
-
   return (
     fetch('http://hipstagram.node.ed.asmer.org.ua/upload', {
       method: 'POST',

+ 2 - 1
js/Project/project/src/components/redux/reducers.js

@@ -55,7 +55,8 @@ export function authReducer(state = {}, { type, token }) {
     }
 
     if (type === 'AUTH_LOGOUT') {
-        localStorage.removeItem('authToken')
+        // localStorage.removeItem('authToken')
+        localStorage.clear()
         return {}
     }
 

+ 135 - 112
js/Project/project/src/components/structure/header.js

@@ -1,140 +1,163 @@
 import React, { useState } from 'react';
-import { useHistory, Link } from 'react-router-dom';
-import { connect } from 'react-redux';
+import { useHistory } from 'react-router-dom';
+import { connect, useDispatch } from 'react-redux';
 
-import { AppBar, Box, Toolbar, Typography, Menu, Container, Avatar, Tooltip, MenuItem, IconButton } from '@mui/material'
+import { AppBar, Box, Toolbar, Typography, Menu, Container, Avatar, Tooltip, MenuItem, IconButton, Stack } from '@mui/material'
 import { Instagram, AddAPhotoRounded } from '@mui/icons-material';
+import { actionFullLogout } from '../redux/action';
 
+import { url } from '../../App';
 
 
-// отрисовываем логин
-const UserName = ({ login }) => <span>{login}</span>
-const CUserName = connect(state => ({ login: state.auth.payload?.sub?.login }))(UserName)
-
-// отрисовывваем логин вариант 2
-const UserName2 = ({ user }) =>
-    <MenuItem key={1} >
-        <Typography textAlign="center" onClick={() => console.log('click login')}>
-            <span>{user.login}</span>
-        </Typography>
-    </MenuItem>
+function UserMenu({ login }) {
+    let history = useHistory()
+    const [anchorElUser, setAnchorElUser] = useState(null)
+    const dispatch = useDispatch()
 
-const CUserName2 = connect(state => ({ user: state.auth.payload?.sub }))(UserName2)
 
+    const handleOpenUserMenu = (event) => {
+        setAnchorElUser(event.currentTarget)
+    }
 
+    const handleCloseUserMenu = () => {
+        setAnchorElUser(null)
+    }
 
-// ====================
-function ResponsiveAppBar() {
-    let history = useHistory()
+    function toMyAccount() {
+        history.push(`/user/${login?._id}`)
+    }
 
-    function goToMyAccount() {
-        history.push('/user/63f8d0c273ca650acb9353f3');
+    function toCreatePost() {
+        history.push('/createpost')
     }
 
-    const [anchorElUser, setAnchorElUser] = useState(null);
+    return (
+        <Stack
+            direction='row'
+        >
+            <IconButton
+                sx={{
+                    color: '#000'
+                }}
+                onClick={toCreatePost}
+            >
+                <AddAPhotoRounded />
+            </IconButton>
+
+            <Box sx={{ flexGrow: 0 }}>
+                <Tooltip>
+                    <IconButton
+                        onClick={handleOpenUserMenu}
+                    >
+                        <Avatar
+                            alt={login?.login}
+                            src={url.slice(0, -7) + login?.avatar?.url}
+                        />
+                    </IconButton>
+                </Tooltip>
+
+                <Menu
+                    sx={{
+                        mt: '50px'
+                    }}
+                    id="menu-appbar"
+                    anchorEl={anchorElUser}
+                    anchorOrigin={{
+                        vertical: 'top',
+                        horizontal: 'right',
+                    }}
+                    keepMounted
+                    transformOrigin={{
+                        vertical: 'top',
+                        horizontal: 'right',
+                    }}
+                    open={Boolean(anchorElUser)}
+                    onClose={handleCloseUserMenu}
+                >
+                    <MenuItem
+                        key={1}
+                        onClick={toMyAccount}
+                    >
+                        <Typography
+                            textAlign="center">
+                            <span>
+                                {login?.login}
+                            </span>
+                        </Typography>
+                    </MenuItem>
+
+                    <MenuItem
+                        key={2}
+                        onClick={() => { dispatch(actionFullLogout()) }}
+                    >
+                        <Typography
+                            textAlign="center"
+                        >
+                            <span>
+                                Выйти
+                            </span>
+                        </Typography>
+                    </MenuItem>
+                </Menu>
+            </Box>
+        </Stack>
+    )
+}
 
-    const handleOpenUserMenu = (event) => {
-        setAnchorElUser(event.currentTarget);
-    };
+function Header({ login }) {
+    let history = useHistory()
 
-    const handleCloseUserMenu = () => {
-        setAnchorElUser(null);
-    };
+    function toMain() {
+        history.push('/');
+    }
 
     return (
-        <AppBar position='sticky' color='inherit'>
-            <Container maxWidth="xl">
-                <Toolbar disableGutters>
-                    <IconButton edge='start'>
-                        <Instagram sx={{
-                            // display: { xs: 'flex' },
-                            color: 'black'
-                        }} />
-                    </IconButton>
-
-                    <Typography
-                        variant="h6"
-                        noWrap
-                        component="a"
-                        href="/"
+        <AppBar
+            position='sticky'
+            color='inherit'
+        >
+            <Container
+                maxWidth="xl"
+            >
+                <Toolbar
+                    disableGutters
+                >
+                    <Stack
+                        direction='row'
                         sx={{
-                            display: { xs: 'none', md: 'flex' },
-                            fontFamily: 'monospace',
-                            fontWeight: 700,
-                            letterSpacing: '.3rem',
-                            color: 'inherit',
-                            textDecoration: 'none',
-                            flexGrow: '1',
-                            ml: 1
+                            display: 'flex',
+                            flexGrow: '1'
                         }}
                     >
-                        Hipstagram
-                    </Typography>
-
-                    <IconButton>
-                        <Link to='/createpost'>
-                            <AddAPhotoRounded sx={{
-                                display: { xs: 'flex' },
-                                mr: 1,
-                                // color: 'black'
-                            }} />
-                        </Link>
-                    </IconButton>
-
-                    <Box sx={{ flexGrow: 0 }}>
-                        <Tooltip >
-                            <IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
-                                <Avatar alt="Remy Sharp" src="/static/images/avatar/2.jpg" />
-                            </IconButton>
-                        </Tooltip>
-                        <Menu
-                            sx={{ mt: '45px' }}
-                            id="menu-appbar"
-                            anchorEl={anchorElUser}
-                            anchorOrigin={{
-                                vertical: 'top',
-                                horizontal: 'right',
+                        <IconButton
+                            edge='start'
+                            sx={{
+                                color: '#000'
                             }}
-                            keepMounted
-                            transformOrigin={{
-                                vertical: 'top',
-                                horizontal: 'right',
-                            }}
-                            open={Boolean(anchorElUser)}
-                            onClose={handleCloseUserMenu}
+                            onClick={toMain}
                         >
-                            {/* <CUserName2 /> */}
-
-                            <MenuItem key={1} onClick={goToMyAccount}>
-                                <Typography textAlign="center">
-                                    <CUserName />
-                                </Typography>
-                            </MenuItem>
-
-                            <MenuItem key={2} onClick={() => console.log('click logout')}>
-                                <Typography textAlign="center">
-                                    <span>Выйти</span>
-                                </Typography>
-                            </MenuItem>
-                        </Menu>
-                    </Box>
+                            <Instagram />
+
+                            <Typography
+                                variant="h6"
+                                sx={{
+                                    fontFamily: 'monospace',
+                                    fontWeight: 700,
+                                    letterSpacing: '.3rem',
+                                    ml: 1
+                                }}
+                            >
+                                Hipstagram
+                            </Typography>
+                        </IconButton>
+                    </Stack>
+
+                    {localStorage.authToken && <UserMenu login={login} />}
+
                 </Toolbar>
             </Container>
         </AppBar>
     )
 }
 
-export default ResponsiveAppBar;
-
-
-
-
-
-
-// <Container>
-//     <Link to="/createpost" style={{ textDecoration: 'none' }}>
-//         <Button variant="contained" color='primary' startIcon={<AddAPhotoRoundedIcon />} onClick={() => (console.log('click add'))}>
-//             Добавить пост
-//         </Button>
-//     </Link>
-// </Container>
+export const CHeader = connect(state => ({ login: state?.promise?.AboutMe?.payload }))(Header)