Browse Source

18.03.2023 03:10

Volddemar4ik 1 year ago
parent
commit
2b6ad67c26

+ 62 - 16
js/Project/project/src/App.js

@@ -12,10 +12,11 @@ import { CUser } from './components/user';
 import { CFeed } from './components/feed';
 import { CComments } from './components/post';
 import { CreatePost } from './components/create_post';
-import Authorization from './components/auth_reg';
+import AuthReg from './components/auth_reg';
 // import Header from './components/structure/header';
 import { CHeader } from './components/structure/header';
 import Footer from './components/structure/footer';
+import Search from './components/search';
 
 // url проекта
 export const url = 'http://hipstagram.node.ed.asmer.org.ua/graphql'
@@ -52,13 +53,6 @@ const history = createHistory()
 
 
 
-
-
-const Registration = () =>
-    <div>
-        Регистрация
-    </div>
-
 const Page404 = () =>
     <div>
         NOT FOUND
@@ -79,6 +73,30 @@ const PrivateRoute = ({ component: Component, ...rest }) => (
 )
 
 
+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>
+{/* </> */ }
+
 
 export default function App() {
     return (
@@ -88,13 +106,7 @@ export default function App() {
                     <CHeader />
                     <main style={{ flexGrow: '1' }}>
                         <Switch>
-                            <PrivateRoute path="/" component={CFeed} 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="*" component={Page404} />
+                            <MyRoutes />
                         </Switch>
                     </main>
                     <Footer />
@@ -103,4 +115,38 @@ export default function App() {
         </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>
+
+//     )
+// }

js/Project/project/src/components/auth_reg/index(copy).js → js/Project/project/src/components/auth_reg/index(classic).js


+ 165 - 0
js/Project/project/src/components/auth_reg/index(privateRoute).js

@@ -0,0 +1,165 @@
+import React from 'react'
+import { store } from '../redux';
+import { useState } from "react";
+import { Link, Redirect } from "react-router-dom";
+import { actionFullLogin } from "../redux/action";
+
+import { Paper, Box, Typography, Button, Stack, OutlinedInput, IconButton, InputLabel, InputAdornment, FormControl } from "@mui/material";
+
+import { Visibility, VisibilityOff } from '@mui/icons-material';
+
+// поля логин/пароль/кнопка входа
+const LoginForm = ({ onLogin }) => {
+    // отслеживаем введение данных в полях логин/пароль
+    const [login, setLogin] = useState('')
+    const [pass, setPass] = useState('')
+
+    // включаем,выклюаем отображение пароля
+    const [showPassword, setShowPassword] = useState(false);
+    const handleClickShowPassword = () => setShowPassword((show) => !show);
+    const handleMouseDownPassword = (event) => {
+        event.preventDefault();
+    };
+
+
+
+    return (
+        <Box sx={{ width: '100%' }}>
+            <Stack spacing={2}>
+                <FormControl variant="outlined">
+                    <InputLabel htmlFor="outlined-adornment-password">Имя пользователя</InputLabel>
+                    <OutlinedInput
+                        id="login"
+                        label="Имя пользователя"
+                        type="text"
+                        size="small"
+                        value={login}
+                        onChange={e => setLogin(e.target.value)}
+                    />
+                </FormControl>
+
+                <FormControl variant="outlined">
+                    <InputLabel htmlFor="outlined-adornment-password">Пароль</InputLabel>
+                    <OutlinedInput
+                        id="password"
+                        label="Пароль"
+                        size="small"
+                        type={showPassword ? 'text' : 'password'}
+                        value={pass}
+                        onChange={e => setPass(e.target.value)}
+
+                        endAdornment={
+                            <InputAdornment position="end">
+                                <IconButton
+                                    aria-label="toggle password visibility"
+                                    onClick={handleClickShowPassword}
+                                    onMouseDown={handleMouseDownPassword}
+                                    edge="end"
+                                >
+                                    {showPassword ? <VisibilityOff /> : <Visibility />}
+                                </IconButton>
+                            </InputAdornment>
+                        }
+                    />
+                </FormControl>
+
+                <Button
+                    variant="contained"
+                    disabled={((login == '') || (pass == '')) || false}
+                    onClick={() => onLogin(login, pass)}
+                >
+                    Войти
+                </Button>
+            </Stack>
+        </Box>
+    )
+}
+
+class Authorization extends React.Component {
+
+    state = {
+        redirectToReferrer: false
+    }
+    login = () => {
+        this.setState(() => ({
+            redirectToReferrer: true
+        }))
+    }
+    render() {
+        const { from } = this.props.location.state || { from: { pathname: '/' } }
+        const { redirectToReferrer } = this.state
+
+        if (redirectToReferrer === true) {
+            return <Redirect to={from} />
+        }
+
+        return (
+            <Box sx={{
+                display: 'grid',
+                height: '80vh',
+                justifyContent: 'center',
+                alignItems: 'center'
+            }}>
+                <Paper elevation={3}
+                    sx={{
+                        padding: '5px',
+                        width: '400px',
+                        height: '500px',
+                        display: 'grid',
+                        justifyContent: 'center',
+                        alignItems: 'center'
+                    }}>
+                    <Typography
+                        variant="h4"
+                        noWrap
+                        sx={{
+                            display: 'grid',
+                            fontFamily: 'monospace',
+                            fontWeight: 700,
+                            letterSpacing: '.3rem',
+                            color: 'inherit',
+                            textDecoration: 'none',
+                            flexGrow: '1',
+                            marginTop: '20px',
+                            justifyContent: 'center'
+                        }} >
+                        Hipstagram
+                    </Typography>
+
+                    <Box
+                        sx={{
+                            display: 'grid',
+                            alignSelf: 'start'
+                        }}>
+                        <LoginForm
+                            onLogin={async (login, pass) => {
+                                await store.dispatch(actionFullLogin(login, pass))
+
+                                this.login()
+                            }}
+                            onClick={() => { console.log('click on login') }}
+
+                        />
+                    </Box>
+
+                    <Typography
+                        variant="subtitle1"
+                        sx={{
+                            display: 'grid',
+                            alignSelf: 'end',
+                            justifyContent: 'center',
+                        }}>
+                        <Link
+                            color="inherit"
+                            to='/registration'
+                        >
+                            Зарегистрироваться
+                        </Link>
+                    </Typography>
+                </Paper>
+            </Box >
+        )
+    }
+}
+
+export default Authorization

+ 221 - 126
js/Project/project/src/components/auth_reg/index.js

@@ -1,18 +1,54 @@
-import React from 'react'
+import * as React from 'react';
 import { store } from '../redux';
 import { useState } from "react";
-import { Link, Redirect } from "react-router-dom";
+import { useHistory, useLocation } from "react-router-dom";
 import { actionFullLogin } from "../redux/action";
 
-import { Paper, Box, Typography, Button, Stack, OutlinedInput, IconButton, InputLabel, InputAdornment, FormControl } from "@mui/material";
+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 LoginForm = ({ onLogin }) => {
+// появление модального окна
+const Transition = React.forwardRef(function Transition(props, ref) {
+    return <Slide direction="up" ref={ref} {...props} />;
+})
+
+
+// поля ввода и кнопки
+function LoginForm() {
+    let location = useLocation();
+
+    const history = useHistory();
+
+    //  модальное окно 
+    const [open, setOpen] = useState(false);
+    const handleOpen = () => {
+        setOpen(true);
+    }
+    const handleClose = () => {
+        setOpen(false);
+    }
+
+
     // отслеживаем введение данных в полях логин/пароль
-    const [login, setLogin] = useState('')
-    const [pass, setPass] = useState('')
+    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;
+
+    ((data.pass.length < passLength) || !(pattern.test(data.pass))) && (isValidate = true);
+    (data.pass != data.confirmPass) && (isCorrect = true);
+
+    const validation = (data.login == '') || (data.pass == '')
+
 
     // включаем,выклюаем отображение пароля
     const [showPassword, setShowPassword] = useState(false);
@@ -21,144 +57,203 @@ const LoginForm = ({ onLogin }) => {
         event.preventDefault();
     };
 
+    // включаем,выклюаем отображение подтверждения пароля
+    const [showPasswordConfirm, setShowPasswordConfirm] = useState(false);
+    const handleClickShowPasswordConfirm = () => setShowPasswordConfirm((show) => !show);
+    const handleMouseDownPasswordConfirm = (event) => {
+        event.preventDefault();
+    };
+
+    async function fullLogin() {
+        const answer = await store.dispatch(actionFullLogin(data.login, data.pass))
+
+        if (answer == null) {
+            handleOpen()
+        }
 
+        if (store.getState()?.auth?.token) {
+            history.push('/')
+        }
+    }
 
     return (
         <Box sx={{ width: '100%' }}>
-            <Stack spacing={2}>
-                <FormControl variant="outlined">
-                    <InputLabel htmlFor="outlined-adornment-password">Имя пользователя</InputLabel>
-                    <OutlinedInput
-                        id="login"
-                        label="Имя пользователя"
-                        type="text"
-                        size="small"
-                        value={login}
-                        onChange={e => setLogin(e.target.value)}
+            <form>
+                <Stack spacing={2}>
+                    <TextField
+                        fullWidth
+                        variant='outlined'
+                        id='login'
+                        label='Логин'
+                        size='normal'
+                        value={data.login}
+                        onChange={e => setData({ ...data, login: e.target.value })}
                     />
-                </FormControl>
-
-                <FormControl variant="outlined">
-                    <InputLabel htmlFor="outlined-adornment-password">Пароль</InputLabel>
-                    <OutlinedInput
-                        id="password"
-                        label="Пароль"
-                        size="small"
-                        type={showPassword ? 'text' : 'password'}
-                        value={pass}
-                        onChange={e => setPass(e.target.value)}
-
-                        endAdornment={
-                            <InputAdornment position="end">
-                                <IconButton
-                                    aria-label="toggle password visibility"
-                                    onClick={handleClickShowPassword}
-                                    onMouseDown={handleMouseDownPassword}
-                                    edge="end"
-                                >
-                                    {showPassword ? <VisibilityOff /> : <Visibility />}
-                                </IconButton>
-                            </InputAdornment>
-                        }
-                    />
-                </FormControl>
 
-                <Button
-                    variant="contained"
-                    disabled={((login == '') || (pass == '')) || false}
-                    onClick={() => onLogin(login, pass)}
+                    <FormControl variant="outlined">
+                        <InputLabel htmlFor="outlined-adornment-password">Пароль</InputLabel>
+                        <OutlinedInput
+                            error={isValidate}
+                            fullWidth
+                            id="password"
+                            label="Пароль"
+                            size="normal"
+                            type={showPassword ? 'text' : 'password'}
+                            value={data.pass}
+                            onChange={e => setData({ ...data, pass: e.target.value })}
+
+                            endAdornment={
+                                <InputAdornment position="end">
+                                    <IconButton
+                                        aria-label="visibility"
+                                        onClick={handleClickShowPassword}
+                                        onMouseDown={handleMouseDownPassword}
+                                        edge="end"
+                                    >
+                                        {showPassword ? <VisibilityOff /> : <Visibility />}
+                                    </IconButton>
+                                </InputAdornment>
+                            }
+                        />
+                    </FormControl>
+
+                    {(location.pathname === '/registration') && <FormControl variant="outlined">
+                        <InputLabel htmlFor="outlined-adornment-password">Подтвердите пароль</InputLabel>
+                        <OutlinedInput
+                            error={isCorrect}
+                            fullWidth
+                            id="confirmPassword"
+                            label="Подтвердите пароль"
+                            size="normal"
+                            type={showPasswordConfirm ? 'text' : 'password'}
+                            value={data.confirmPass}
+                            onChange={e => setData({ ...data, confirmPass: e.target.value })}
+
+                            endAdornment={
+                                <InputAdornment position="end">
+                                    <IconButton
+                                        aria-label="visibility"
+                                        onClick={handleClickShowPasswordConfirm}
+                                        onMouseDown={handleMouseDownPasswordConfirm}
+                                        edge="end"
+                                    >
+                                        {showPasswordConfirm ? <VisibilityOff /> : <Visibility />}
+                                    </IconButton>
+                                </InputAdornment>
+                            }
+                        />
+                    </FormControl>}
+
+                    <Button
+                        size="large"
+                        variant="contained"
+                        disabled={location.pathname === '/' ?
+                            (validation || false) :
+                            (validation || isCorrect) || false}
+                        onClick={fullLogin}
+                    >
+                        {location.pathname === '/' ? 'Войти' : 'Регистрация'}
+                    </Button>
+                </Stack>
+            </form>
+
+            <div>
+                <Dialog
+                    open={open}
+                    onClose={handleClose}
+                    TransitionComponent={Transition}
+                // keepMounted // всегда держит компонент смонтированным в DOM
                 >
-                    Войти
-                </Button>
-            </Stack>
+                    <DialogTitle>Что-то пошло не так!</DialogTitle>
+                    <DialogContent>
+                        <DialogContentText>
+                            Вы ввели неправильный логин или пароль. Повторите попытку.
+                        </DialogContentText>
+                    </DialogContent>
+                    <DialogActions>
+                        <Button onClick={handleClose}>Ок</Button>
+                    </DialogActions>
+                </Dialog>
+            </div>
         </Box>
     )
 }
 
-class Authorization extends React.Component {
 
-    state = {
-        redirectToReferrer: false
-    }
-    login = () => {
-        this.setState(() => ({
-            redirectToReferrer: true
-        }))
-    }
-    render() {
-        const { from } = this.props.location.state || { from: { pathname: '/' } }
-        const { redirectToReferrer } = this.state
+function RegistrationLink() {
+    const history = useHistory()
 
-        if (redirectToReferrer === true) {
-            return <Redirect to={from} />
-        }
+    function goToRegistration() {
+        history.push('/registration')
+    }
 
-        return (
-            <Box sx={{
+    return (
+        <Typography
+            variant="subtitle1"
+            sx={{
                 display: 'grid',
-                height: '80vh',
+                alignSelf: 'end',
                 justifyContent: 'center',
-                alignItems: 'center'
-            }}>
-                <Paper elevation={3}
+                cursor: 'pointer'
+            }}
+            onClick={goToRegistration}
+        >
+            Зарегистрироваться
+        </Typography>
+    )
+}
+
+
+function AuthReg() {
+
+    let location = useLocation();
+
+    return (
+        <Box sx={{
+            display: 'grid',
+            height: '80vh',
+            justifyContent: 'center',
+            alignItems: 'center'
+        }}>
+
+            <Paper elevation={3}
+                sx={{
+                    padding: '5px',
+                    width: '400px',
+                    height: '500px',
+                    display: 'grid',
+                    justifyContent: 'center',
+                    alignItems: 'center'
+                }}>
+                <Typography
+                    variant="h4"
+                    noWrap
                     sx={{
-                        padding: '5px',
-                        width: '400px',
-                        height: '500px',
                         display: 'grid',
-                        justifyContent: 'center',
-                        alignItems: 'center'
+                        fontFamily: 'monospace',
+                        fontWeight: 700,
+                        letterSpacing: '.3rem',
+                        color: 'inherit',
+                        textDecoration: 'none',
+                        flexGrow: '1',
+                        marginTop: '20px',
+                        justifyContent: 'center'
+                    }} >
+                    Hipstagram
+                </Typography>
+
+                <Box
+                    sx={{
+                        display: 'grid',
+                        alignSelf: 'start'
                     }}>
-                    <Typography
-                        variant="h4"
-                        noWrap
-                        sx={{
-                            display: 'grid',
-                            fontFamily: 'monospace',
-                            fontWeight: 700,
-                            letterSpacing: '.3rem',
-                            color: 'inherit',
-                            textDecoration: 'none',
-                            flexGrow: '1',
-                            marginTop: '20px',
-                            justifyContent: 'center'
-                        }} >
-                        Hipstagram
-                    </Typography>
-
-                    <Box
-                        sx={{
-                            display: 'grid',
-                            alignSelf: 'start'
-                        }}>
-                        <LoginForm
-                            onLogin={async (login, pass) => {
-                                await store.dispatch(actionFullLogin(login, pass))
-
-                                this.login()
-                            }}
+                    <LoginForm />
+                </Box>
 
-                        />
-                    </Box>
-
-                    <Typography
-                        variant="subtitle1"
-                        sx={{
-                            display: 'grid',
-                            alignSelf: 'end',
-                            justifyContent: 'center',
-                        }}>
-                        <Link
-                            color="inherit"
-                            to='/registration'
-                        >
-                            Зарегистрироваться
-                        </Link>
-                    </Typography>
-                </Paper>
-            </Box >
-        )
-    }
+                {(location.pathname === '/') && <RegistrationLink />}
+            </Paper>
+        </Box >
+    )
 }
 
-export default Authorization
+export default AuthReg

+ 212 - 0
js/Project/project/src/components/auth_reg/modal.js

@@ -0,0 +1,212 @@
+import { store } from '../redux';
+import { useState } from "react";
+import { useHistory, useParams, useLocation } from "react-router-dom";
+import { actionFullLogin } from "../redux/action";
+import { ExampleModal } from './modal';
+
+import { Paper, Box, Typography, Button, Stack, OutlinedInput, IconButton, InputLabel, InputAdornment, FormControl, TextField } from "@mui/material";
+
+import { Visibility, VisibilityOff } from '@mui/icons-material';
+
+
+// поля ввода и кнопки
+function LoginForm() {
+    const history = useHistory();
+
+    // отслеживаем введение данных в полях логин/пароль
+    const [data, setData] = useState({ login: '', pass: '' })
+
+    // включаем,выклюаем отображение пароля
+    const [showPassword, setShowPassword] = useState(false);
+    const handleClickShowPassword = () => setShowPassword((show) => !show);
+    const handleMouseDownPassword = (event) => {
+        event.preventDefault();
+    };
+
+    async function fullLogin() {
+        const answer = await store.dispatch(actionFullLogin(data.login, data.pass))
+
+        console.log('answer: ', answer)
+        if (answer == null) {
+            console.log('nul')
+            return (
+                <ExampleModal />
+            )
+        }
+
+        if (store.getState()?.auth?.token) {
+            history.push('/')
+        }
+    }
+
+    return (
+        <Box sx={{ width: '100%' }}>
+            <form>
+                <Stack spacing={2}>
+                    <TextField
+                        fullWidth
+                        variant='outlined'
+                        id='login'
+                        label='Логин'
+                        size='normal'
+                        value={data.login}
+                        onChange={e => setData({ ...data, login: e.target.value })}
+                    />
+
+                    <FormControl variant="outlined">
+                        <InputLabel htmlFor="outlined-adornment-password">Пароль</InputLabel>
+                        <OutlinedInput
+                            fullWidth
+                            id="password"
+                            label="Пароль"
+                            size="normal"
+                            type={showPassword ? 'text' : 'password'}
+                            value={data.pass}
+                            onChange={e => setData({ ...data, pass: e.target.value })}
+
+                            endAdornment={
+                                <InputAdornment position="end">
+                                    <IconButton
+                                        aria-label="visibility"
+                                        onClick={handleClickShowPassword}
+                                        onMouseDown={handleMouseDownPassword}
+                                        edge="end"
+                                    >
+                                        {showPassword ? <VisibilityOff /> : <Visibility />}
+                                    </IconButton>
+                                </InputAdornment>
+                            }
+                        />
+                    </FormControl>
+
+                    <Button
+                        size="large"
+                        variant="contained"
+                        disabled={((data.login == '') || (data.pass == '')) || false}
+                        onClick={fullLogin}
+                    >
+                        Войти
+                    </Button>
+                </Stack>
+            </form>
+        </Box>
+    )
+}
+
+
+function RegistrationLink() {
+    const history = useHistory()
+
+    function goToRegistration() {
+        history.push('/registration')
+    }
+
+    return (
+        <Typography
+            variant="subtitle1"
+            sx={{
+                display: 'grid',
+                alignSelf: 'end',
+                justifyContent: 'center',
+                cursor: 'pointer'
+            }}
+            onClick={goToRegistration}
+        >
+            Зарегистрироваться
+        </Typography>
+    )
+}
+
+
+function AuthReg() {
+
+    let location = useLocation();
+    console.log('location: ', location.pathname)
+
+    return (
+        <Box sx={{
+            display: 'grid',
+            height: '80vh',
+            justifyContent: 'center',
+            alignItems: 'center'
+        }}>
+
+            <Paper elevation={3}
+                sx={{
+                    padding: '5px',
+                    width: '400px',
+                    height: '500px',
+                    display: 'grid',
+                    justifyContent: 'center',
+                    alignItems: 'center'
+                }}>
+                <Typography
+                    variant="h4"
+                    noWrap
+                    sx={{
+                        display: 'grid',
+                        fontFamily: 'monospace',
+                        fontWeight: 700,
+                        letterSpacing: '.3rem',
+                        color: 'inherit',
+                        textDecoration: 'none',
+                        flexGrow: '1',
+                        marginTop: '20px',
+                        justifyContent: 'center'
+                    }} >
+                    Hipstagram
+                </Typography>
+
+                <Box
+                    sx={{
+                        display: 'grid',
+                        alignSelf: 'start'
+                    }}>
+                    <LoginForm />
+                </Box>
+
+                {(location.pathname === '/') && <RegistrationLink />}
+            </Paper>
+        </Box >
+    )
+}
+
+
+
+
+function Registration2() {
+    let location = useLocation();
+    console.log('location: ', location.pathname)
+
+
+    return (
+        <div> тут будет регистрация, которая из авторизации</div>
+    )
+}
+
+
+
+
+
+
+// function AuthReg() {
+
+//     let location = useLocation();
+//     console.log('location: ', location.pathname)
+
+
+//     return (
+//         <>
+//             {(location.pathname === '/') ? <Authorization /> : <Registration2 />}
+//         </>
+//     )
+
+// }
+function Authorization() {
+    return (
+        <></>
+    )
+}
+
+
+export { Authorization, Registration2, AuthReg }

+ 25 - 1
js/Project/project/src/components/redux/action.js

@@ -40,6 +40,7 @@ const gql = getGql(url)
 export const actionPending = nameOfPromise => ({ nameOfPromise, type: 'PROMISE', status: 'PENDING' })
 export const actionFulfilled = (nameOfPromise, payload) => ({ nameOfPromise, type: 'PROMISE', status: 'FULFILLED', payload })
 export const actionRejected = (nameOfPromise, error) => ({ nameOfPromise, type: 'PROMISE', status: 'REJECTED', error })
+
 export const actionPromise = (nameOfPromise, promise) =>
   async dispatch => {
     dispatch(actionPending(nameOfPromise)) //сигнализируем redux, что промис начался
@@ -172,6 +173,21 @@ 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-и
 
@@ -186,6 +202,8 @@ export const actionFullLogin = (login, password) =>
           dispatch(actionAuthLogin(token))
           localStorage.authToken = token
         }
+      } else {
+        return token
       }
     }
 
@@ -202,7 +220,13 @@ export const actionFullLogout = () =>
     await dispatch(actionAuthLogout())
 
     // и перебрасываем пользователя на страницу авторизации
-    window.location.replace('/authorization')
+    // window.location.replace('/authorization')
+
+
+    setTimeout(function () {
+      window.location.replace('/')
+    }, 500)
+
   }
 
 

+ 1 - 1
js/Project/project/src/components/redux/index.js

@@ -1,7 +1,7 @@
 import { createStore, combineRedusers, applyMiddleware } from 'redux';
 import thunk from "redux-thunk";
 
-import { promiseReducer, localStoredReducer, totalReducer, authReducer } from "./reducers";
+import { totalReducer } from "./reducers";
 
 import { actionPending, actionFulfilled, actionRejected, actionPromise, actionFullLogin, actionLogin } from "./action";
 

+ 39 - 20
js/Project/project/src/components/redux/reducers.js

@@ -1,6 +1,18 @@
-// promiseReducer
 import { combineReducers } from "redux"
 
+// feedReducer - а нужен ли он?
+// export function feedReducer(state = {}, { type, status, payload, error, nameOfPromise }) {
+//     if (type === 'PROMISE') {
+//         return {
+//             ...state,
+//             [nameOfPromise]: { status, payload, error }
+//         }
+//     }
+// }
+
+
+
+// promiseReducer
 export function promiseReducer(state = {}, { type, status, payload, error, nameOfPromise }) {
     if (type === 'PROMISE') {
         return {
@@ -11,27 +23,10 @@ export function promiseReducer(state = {}, { type, status, payload, error, nameO
     return state
 }
 
-// localStoredReducer
-export function localStoredReducer(originalReducer, localStorageKey) {
-    function wrapper(state, action) {
-        if (!state) {
-            try {
-                return JSON.parse(localStorage[localStorageKey])
-            }
-            catch (error) {
 
-            }
-        }
-        const newState = originalReducer(state, action)
-        localStorage[localStorageKey] = JSON.stringify(newState)
 
-        return newState
-    }
 
-    return wrapper
-}
 
-// authReducer
 // раскодируем JWT-токен
 const jwtDecode = function (token) {
     try {
@@ -43,6 +38,7 @@ const jwtDecode = function (token) {
     }
 }
 
+// authReducer
 export function authReducer(state = {}, { type, token }) {
     if (type === 'AUTH_LOGIN') {
 
@@ -64,12 +60,35 @@ export function authReducer(state = {}, { type, token }) {
 }
 
 
-// 1 изменение 
+
+
+// localStoredReducer, который обрабатывает все наши редьюсеры для разных направлений
+export function localStoredReducer(originalReducer, localStorageKey) {
+    function wrapper(state, action) {
+        if (!state) {
+            try {
+                return JSON.parse(localStorage[localStorageKey])
+            }
+            catch (error) {
+
+            }
+        }
+        const newState = originalReducer(state, action)
+        localStorage[localStorageKey] = JSON.stringify(newState)
+
+        return newState
+    }
+
+    return wrapper
+}
+
+// создаем объект с редьюсерами
 export const reducers = {
     promise: localStoredReducer(promiseReducer, 'promise'),
     auth: localStoredReducer(authReducer, 'auth'),
-    // cart: localStoredReducer(cartReducer, 'cart'),
+    // feed: localStoredReducer(feedReducer, 'feed')
 }
 
+// скармливаем объект с редьюсерами в combineReducers
 export const totalReducer = combineReducers(reducers)
 

+ 7 - 0
js/Project/project/src/components/search/index.js

@@ -0,0 +1,7 @@
+export default function Search() {
+    return (
+        <div>
+            тут будет страница поиска
+        </div>
+    )
+}

+ 13 - 61
js/Project/project/src/components/structure/header.js

@@ -32,65 +32,6 @@ import InputBase from '@mui/material/InputBase';
 
 import { url } from '../../App';
 
-function SearchField() {
-    const Search = styled('div')(({ theme }) => ({
-        position: 'relative',
-        borderRadius: theme.shape.borderRadius,
-        backgroundColor: alpha(theme.palette.common.white, 0.15),
-        '&:hover': {
-            backgroundColor: alpha(theme.palette.common.white, 0.25),
-        },
-        marginLeft: 0,
-        width: '100%',
-        [theme.breakpoints.up('sm')]: {
-            marginLeft: theme.spacing(1),
-            width: 'auto',
-        },
-    }));
-
-    const SearchIconWrapper = styled('div')(({ theme }) => ({
-        padding: theme.spacing(0, 2),
-        height: '100%',
-        position: 'absolute',
-        pointerEvents: 'none',
-        display: 'flex',
-        alignItems: 'center',
-        justifyContent: 'center',
-    }));
-
-    const StyledInputBase = styled(InputBase)(({ theme }) => ({
-        color: 'inherit',
-        '& .MuiInputBase-input': {
-            padding: theme.spacing(1, 1, 1, 0),
-            // vertical padding + font size from searchIcon
-            paddingLeft: `calc(1em + ${theme.spacing(4)})`,
-            transition: theme.transitions.create('width'),
-            width: '100%',
-            [theme.breakpoints.up('sm')]: {
-                width: '12ch',
-                '&:focus': {
-                    width: '20ch',
-                },
-            },
-        },
-    }));
-
-
-
-    return (
-        <Search>
-            <SearchIconWrapper>
-                <SearchIcon />
-            </SearchIconWrapper>
-            <StyledInputBase
-                placeholder="Search…"
-                inputProps={{ 'aria-label': 'search' }}
-            />
-        </Search>
-    )
-}
-
-
 
 
 function UserMenu({ login }) {
@@ -115,12 +56,23 @@ function UserMenu({ login }) {
         history.push('/createpost')
     }
 
+    function toSearch() {
+        history.push('/search')
+    }
+
     return (
         <Stack
             direction='row'
         >
-
-            <SearchField />
+            <IconButton
+                sx={{
+                    color: '#000',
+                    transform: 'scale(-1, 1)'
+                }}
+                onClick={toSearch}
+            >
+                <SearchIcon />
+            </IconButton>
 
             <IconButton
                 sx={{