Volddemar4ik 1 год назад
Родитель
Сommit
ae493cabf1

+ 46 - 86
js/Project/project/src/App.js

@@ -1,6 +1,6 @@
-import React from 'react'
+import React, { useEffect, useState } from 'react'
 import { Router, Route, Redirect, withRouter, Switch } from 'react-router-dom';
-import { Provider } from 'react-redux';
+import { Provider, useSelector } from 'react-redux';
 import { store } from './components/redux/index';
 import createHistory from "history/createBrowserHistory";
 
@@ -17,6 +17,7 @@ import AuthReg from './components/auth_reg';
 import { CHeader } from './components/structure/header';
 import Footer from './components/structure/footer';
 import Search from './components/search';
+import Page404 from './components/404/page404';
 
 // url проекта
 export const url = 'http://hipstagram.node.ed.asmer.org.ua/graphql'
@@ -24,6 +25,7 @@ export const url = 'http://hipstagram.node.ed.asmer.org.ua/graphql'
 const history = createHistory()
 
 
+// Приватный роутинг - удалить, если не буду использовать
 
 {
     // фейковый авторизатор
@@ -39,6 +41,8 @@ const history = createHistory()
         }
     }
 
+
+
     // кнопка разлогина, которая рисуется, если залогинен
     const AuthButton = withRouter(({ history }) => (
         fakeAuth.isAuthenticated && (
@@ -49,53 +53,47 @@ const history = createHistory()
             </p>
         )
     ))
-}
 
+    const PrivateRoute = ({ component: Component, ...rest }) => (
+        <Route {...rest} render={(props) => (
+            typeof localStorage.authToken === 'string'
+                ? <Component {...props} />
+                : <Redirect to={{
+                    pathname: '/authorization',
+                    state: { from: props.location }
+                }} />
+        )} />
+    )
 
 
-const Page404 = () =>
-    <div>
-        NOT FOUND
-    </div>
-
-
-
-// Приватный роутинг
-const PrivateRoute = ({ component: Component, ...rest }) => (
-    <Route {...rest} render={(props) => (
-        typeof localStorage.authToken === 'string'
-            ? <Component {...props} />
-            : <Redirect to={{
-                pathname: '/authorization',
-                state: { from: props.location }
-            }} />
-    )} />
-)
-
-
-const MyRoutes = () =>
-    // <>
-    <Switch>
-        {/* <PrivateRoute path="/" component={CFeed} exact /> */}
-        {/* <Route path="/" component={
-            store.getState()?.auth?.token ? CFeed : Authorization
-        } exact
-        /> */}
-        <Route path="/" component={
-            store.getState()?.auth?.token ? CFeed : AuthReg
-        } exact
-        />
-
-        {/* <Route path="/authorization" component={Authorization} /> */}
-        {/* <Route path="/registration" component={Registration2} /> */}
-        <Route path="/registration" component={AuthReg} />
-        <Route path="/post/:postId" component={CComments} />
-        <Route path="/user/:userId" component={CUser} />
-        <Route path="/createpost" component={CreatePost} />
-        <Route path='/search' component={Search} />
-        <Route path="*" component={Page404} />
-    </Switch>
-{/* </> */ }
+}
+
+// роутинг в зависимости от того.залогинен пользователь или нет
+const MainRoutes = () => {
+    const currentState = useSelector(state => state?.auth?.token)
+
+    return (
+        <main style={{ flexGrow: '1' }}>
+            {currentState
+                ? <Switch>
+                    <Route path="/" component={CFeed} exact />
+                    <Route path="/post/:postId" component={CComments} />
+                    <Route path="/user/:userId" component={CUser} />
+                    <Route path="/createpost" component={CreatePost} />
+                    <Route path='/search' component={Search} />
+                    <Route path="*" component={Page404} />
+                </Switch>
+                : <Switch>
+                    <Route path="/" component={AuthReg} exact />
+                    <Route path="/registration" component={AuthReg} />
+                    <Route path="/post/:postId" component={CComments} />
+                    <Route path="/user/:userId" component={CUser} />
+                    <Route path="*" component={Page404} />
+                </Switch>
+            }
+        </main>
+    )
+}
 
 
 export default function App() {
@@ -104,49 +102,11 @@ export default function App() {
             <Router history={history}>
                 <div className="wrapper">
                     <CHeader />
-                    <main style={{ flexGrow: '1' }}>
-                        <Switch>
-                            <MyRoutes />
-                        </Switch>
-                    </main>
+                    <MainRoutes />
                     <Footer />
                 </div>
             </Router>
         </Provider>
 
     )
-}
-
-
-
-
-// export default function App() {
-//     return (
-//         <Provider store={store}>
-//             <Router history={history}>
-//                 <div className="wrapper">
-//                     <CHeader />
-//                     <main style={{ flexGrow: '1' }}>
-//                         <Switch>
-//                             {/* <PrivateRoute path="/" component={CFeed} exact /> */}
-//                             <Route path="/" component={
-//                                 store.getState()?.auth?.token ? CFeed : Authorization
-//                             } exact
-//                             />
-
-//                             <Route path="/authorization" component={Authorization} />
-//                             <Route path="/registration" component={Registration} />
-//                             <Route path="/post/:postId" component={CComments} />
-//                             <Route path="/user/:userId" component={CUser} />
-//                             <Route path="/createpost" component={CreatePost} />
-//                             <Route path='/search' component={Search} />
-//                             <Route path="*" component={Page404} />
-//                         </Switch>
-//                     </main>
-//                     <Footer />
-//                 </div>
-//             </Router>
-//         </Provider>
-
-//     )
-// }
+}

+ 8 - 0
js/Project/project/src/components/404/page404.js

@@ -0,0 +1,8 @@
+
+const Page404 = () =>
+    <div>
+        NOT FOUND
+    </div>
+
+
+export default Page404

+ 81 - 37
js/Project/project/src/components/auth_reg/index.js

@@ -1,45 +1,72 @@
-import * as React from 'react';
+import React, {
+    forwardRef,
+    useState
+} from 'react';
 import { store } from '../redux';
-import { useState } from "react";
-import { useHistory, useLocation } from "react-router-dom";
-import { actionFullLogin } from "../redux/action";
-
-import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle, Paper, Box, Typography, Button, Stack, OutlinedInput, IconButton, InputLabel, InputAdornment, FormControl, TextField, Slide } from "@mui/material";
-
-import { Visibility, VisibilityOff } from '@mui/icons-material';
-
-// появление модального окна
-const Transition = React.forwardRef(function Transition(props, ref) {
+import {
+    useHistory,
+    useLocation
+} from "react-router-dom";
+import { actionFullLogin, actionFullRegistration } from "../redux/action";
+
+import {
+    useDispatch,
+    useSelector
+} from 'react-redux';
+
+import {
+    Dialog,
+    DialogActions,
+    DialogContent,
+    DialogContentText,
+    DialogTitle,
+    Paper,
+    Box,
+    Typography,
+    Button,
+    Stack,
+    OutlinedInput,
+    IconButton,
+    InputLabel,
+    InputAdornment,
+    FormControl,
+    TextField,
+    Slide
+} from "@mui/material";
+
+import {
+    Visibility,
+    VisibilityOff
+} from '@mui/icons-material';
+
+
+// анимация появление модального окна
+const Transition = forwardRef(function Transition(props, ref) {
     return <Slide direction="up" ref={ref} {...props} />;
 })
 
 
 // поля ввода и кнопки
 function LoginForm() {
-    let location = useLocation();
-
+    const location = useLocation();
     const history = useHistory();
 
-    //  модальное окно 
+    // отслеживаем введение данных в полях логин/пароль
+    const [data, setData] = useState({ login: '', pass: '', confirmPass: '' })
+    console.log('data: ', data)
+
+    //  модальное окно открытие/закрытие
     const [open, setOpen] = useState(false);
-    const handleOpen = () => {
+    const openModalAlertWindow = () => {
         setOpen(true);
     }
-    const handleClose = () => {
+    const closeModalAlertWindow = () => {
         setOpen(false);
     }
 
-
-    // отслеживаем введение данных в полях логин/пароль
-    const [data, setData] = useState({ login: '', pass: '', confirmPass: '' })
-    console.log('data: ', data)
-
-
-    // проверка пароля на заданные параметры
-    // регулярка, какие символы должны входить
+    // регулярка для проверки нового пароля
     const pattern = /(?=.*[0-9])(?=.*[!@#$%^&*])(?=.*[a-z])(?=.*[A-Z])/g
-
-    // минимальная длинна пароля
+    // указываем минимальную длинну для нового пароля
     const passLength = 8;
 
     let isValidate, isCorrect;
@@ -64,18 +91,28 @@ function LoginForm() {
         event.preventDefault();
     };
 
-    async function fullLogin() {
-        const answer = await store.dispatch(actionFullLogin(data.login, data.pass))
 
-        if (answer == null) {
-            handleOpen()
-        }
+    // Thunk регистрация
+    async function fullRegistration() {
+        const token = await store.dispatch(actionFullRegistration(data.login, data.confirmPass))
 
-        if (store.getState()?.auth?.token) {
+        if (token !== null) {
             history.push('/')
+        } else {
+            openModalAlertWindow()
+        }
+    }
+
+    // Thunk логинизация
+    async function fullLogin() {
+        const token = await store.dispatch(actionFullLogin(data.login, data.pass))
+
+        if (token == null) {
+            openModalAlertWindow()
         }
     }
 
+
     return (
         <Box sx={{ width: '100%' }}>
             <form>
@@ -150,9 +187,10 @@ function LoginForm() {
                         disabled={location.pathname === '/' ?
                             (validation || false) :
                             (validation || isCorrect) || false}
-                        onClick={fullLogin}
+                        onClick={location.pathname === '/' ? fullLogin : fullRegistration}
                     >
-                        {location.pathname === '/' ? 'Войти' : 'Регистрация'}
+                        {location.pathname === '/'
+                            ? 'Войти' : 'Регистрация'}
                     </Button>
                 </Stack>
             </form>
@@ -160,18 +198,22 @@ function LoginForm() {
             <div>
                 <Dialog
                     open={open}
-                    onClose={handleClose}
+                    onClose={closeModalAlertWindow}
                     TransitionComponent={Transition}
                 // keepMounted // всегда держит компонент смонтированным в DOM
                 >
                     <DialogTitle>Что-то пошло не так!</DialogTitle>
                     <DialogContent>
                         <DialogContentText>
-                            Вы ввели неправильный логин или пароль. Повторите попытку.
+                            {
+                                location.pathname === '/'
+                                    ? 'Вы ввели неправильный логин или пароль. Повторите попытку.'
+                                    : 'Введенные логин и/или пароль уже зарегистрированы'
+                            }
                         </DialogContentText>
                     </DialogContent>
                     <DialogActions>
-                        <Button onClick={handleClose}>Ок</Button>
+                        <Button onClick={closeModalAlertWindow}>Ок</Button>
                     </DialogActions>
                 </Dialog>
             </div>
@@ -180,6 +222,7 @@ function LoginForm() {
 }
 
 
+// действия при нажатии по ссылке на регистрацию
 function RegistrationLink() {
     const history = useHistory()
 
@@ -204,6 +247,7 @@ function RegistrationLink() {
 }
 
 
+// Основное окно регистрации (без полей ввода и кнопок)
 function AuthReg() {
 
     let location = useLocation();

+ 69 - 38
js/Project/project/src/components/redux/action.js

@@ -54,9 +54,55 @@ export const actionPromise = (nameOfPromise, promise) =>
     }
   }
 
+
+
+
+
 // =============================================================
 // Запросы на бек
 
+// Запрос на регистрацию пользователя
+export const actionRegistration = (login, password) => actionPromise('Registration', gql(`mutation Registration($login:String!, $password:String!) {
+   createUser(login:$login, password:$password) {
+    _id login
+  }
+}`, {
+  login,
+  password
+})
+
+)
+
+// Запрос на логинизацию пользователя
+export const actionLogin = (login, password) => actionPromise('Login', gql(`query Login($login: String!, $password: String!) {
+login(login: $login, password: $password)
+}`, {
+  login,
+  password
+}))
+
+
+// акшон для логинизации в authReduser
+const actionAuthLogin = token => ({ type: 'AUTH_LOGIN', token })
+// акшон для раззлогинивания
+const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' })
+
+
+//  запрос на изменение пароля юзера
+export const actionPassChange = (loginChange, passwordChange, passwordNew) => actionPromise('PassChange', gql(`mutation PasswordChange($loginChange: String!, $passwordChange: String!, $passwordNew: String!) {
+  changePassword(
+    login: $loginChange, password: $passwordChange, newPassword: $passwordNew
+  ) {
+       _id login
+
+  }
+}`, {
+  loginChange,
+  passwordChange,
+  passwordNew
+}))
+
+
 // запрос на поиск конкретного поста
 export const actionFindPostOne = _id => actionPromise('PostFindOne', gql(`query OnePostFind ($postOne: String){
   PostFindOne (query: $postOne) {
@@ -158,61 +204,46 @@ export const actionFeedFindOne = (arr, sortOne, promiseName = 'Feed') => actionP
 }))
 
 
-// Запрос на логинизацию пользователя
-export const actionLogin = (login, password) => actionPromise('Login', gql(`query Login($login: String!, $password: String!) {
-login(login: $login, password: $password)
-}`, {
-  login,
-  password
-}))
-
-
-// акшон для логинизации в authReduser
-const actionAuthLogin = token => ({ type: 'AUTH_LOGIN', token })
-// акшон для раззлогинивания
-const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' })
-
-
-//  запрос на изменение пароля юзера
-export const actionPassChange = (loginChange, passwordChange, passwordNew) => actionPromise('PassChange', gql(`mutation PasswordChange($loginChange: String!, $passwordChange: String!, $passwordNew: String!) {
-  changePassword(
-    login: $loginChange, password: $passwordChange, newPassword: $passwordNew
-  ) {
-       _id login
-
-  }
-}`, {
-  loginChange,
-  passwordChange,
-  passwordNew
-}))
 
 
 // =========================================
 // Thunk-и
 
+
 // Thunk логин и последующую логинизацию в authReduser
 export const actionFullLogin = (login, password) =>
   async dispatch => {
+
     const token = await dispatch(actionLogin(login, password))
 
-    try {
-      if (token != null) {
-        if (typeof (token) === 'string') {
-          dispatch(actionAuthLogin(token))
-          localStorage.authToken = token
-        }
-      } else {
-        return token
+    if (token !== null) {
+      if (typeof (token) === 'string') {
+        dispatch(actionAuthLogin(token))
+        localStorage.authToken = token
       }
     }
 
-    catch (error) {
-      console.log(error)
+    return token
+  }
+
+
+// Thunk на регистрацию и последующую логинизацию
+export const actionFullRegistration = (login, password) =>
+  async dispatch => {
+
+    const token = await dispatch(actionRegistration(login, password))
+
+    if (token !== null) {
+      dispatch(actionFullLogin(login, password))
     }
+
+    return token
   }
 
 
+
+
+
 // Thunk разлогина и последующей полной очистки localStorage
 export const actionFullLogout = () =>
   async dispatch => {

+ 4 - 30
js/Project/project/src/components/structure/header.js

@@ -3,42 +3,18 @@ import { useHistory } from 'react-router-dom';
 import { connect, useDispatch } from 'react-redux';
 
 import { AppBar, Box, Toolbar, Typography, Menu, Container, Avatar, Tooltip, MenuItem, IconButton, Stack } from '@mui/material'
-import { Instagram, AddAPhotoRounded, SearchRounded } from '@mui/icons-material';
+import { Instagram, AddAPhotoRounded, Search } from '@mui/icons-material';
 import { actionFullLogout } from '../redux/action';
 
-
-
-
-
-
-
-
-
-
-
-
-import { styled, alpha } from '@mui/material/styles';
-import SearchIcon from '@mui/icons-material/Search';
-import InputBase from '@mui/material/InputBase';
-
-
-
-
-
-
-
-
-
-
 import { url } from '../../App';
 
 
 
 function UserMenu({ login }) {
     let history = useHistory()
-    const [anchorElUser, setAnchorElUser] = useState(null)
     const dispatch = useDispatch()
 
+    const [anchorElUser, setAnchorElUser] = useState(null)
 
     const handleOpenUserMenu = (event) => {
         setAnchorElUser(event.currentTarget)
@@ -71,7 +47,7 @@ function UserMenu({ login }) {
                 }}
                 onClick={toSearch}
             >
-                <SearchIcon />
+                <Search />
             </IconButton>
 
             <IconButton
@@ -114,7 +90,6 @@ function UserMenu({ login }) {
                     onClose={handleCloseUserMenu}
                 >
                     <MenuItem
-                        key={1}
                         onClick={toMyAccount}
                     >
                         <Typography
@@ -126,7 +101,6 @@ function UserMenu({ login }) {
                     </MenuItem>
 
                     <MenuItem
-                        key={2}
                         onClick={() => { dispatch(actionFullLogout()) }}
                     >
                         <Typography
@@ -191,7 +165,7 @@ function Header({ login }) {
                         </IconButton>
                     </Stack>
 
-                    {localStorage.authToken && <UserMenu login={login} />}
+                    {login && <UserMenu login={login} />}
 
                 </Toolbar>
             </Container>