|
@@ -1,210 +0,0 @@
|
|
-import logo from './logo.svg';
|
|
|
|
-import './App.css';
|
|
|
|
-import React, { useState, Component, useEffect, useRef } from "react";
|
|
|
|
-import {Provider, connect} from 'react-redux';
|
|
|
|
-import thunk from 'redux-thunk';
|
|
|
|
-import {createStore, combineReducers,applyMiddleware } from 'redux';
|
|
|
|
-import Form from './components/Form';
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-const getGQL = url =>
|
|
|
|
- (query, variables) =>
|
|
|
|
- fetch(url, {
|
|
|
|
- method: 'POST',
|
|
|
|
- headers: {
|
|
|
|
- "content-type": "application/json",
|
|
|
|
- ...(localStorage.authToken ? {Authorization: "Bearer " + localStorage.authToken} : {})
|
|
|
|
- },
|
|
|
|
- body: JSON.stringify({query, variables})
|
|
|
|
- }).then(res => res.json())
|
|
|
|
-
|
|
|
|
- let gql = getGQL("http://snippet.asmer.fs.a-level.com.ua/graphql")
|
|
|
|
-
|
|
|
|
-function promiseReducer(state , {type, name ,status , payload, error}) {
|
|
|
|
- if (!state){
|
|
|
|
- return {} //{status , payload , error}
|
|
|
|
- }
|
|
|
|
- if (type === 'PROMISE') {
|
|
|
|
- return {
|
|
|
|
- ...state,
|
|
|
|
- [name]: [status,payload , error]
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return state
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-let reg = async(login,password) => {
|
|
|
|
- let query = `mutation reg($l:String! , $p:String!) {
|
|
|
|
- createUser(login:$l,password:$p){
|
|
|
|
- _id
|
|
|
|
-}
|
|
|
|
-}`
|
|
|
|
-
|
|
|
|
- let qVariables = {
|
|
|
|
- "l": login,
|
|
|
|
- "p": password
|
|
|
|
- }
|
|
|
|
- let result = await gql(query,qVariables)
|
|
|
|
- return result
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- let log = async(login , password) => {
|
|
|
|
- let query = ` query log($l:String!,$p:String!) {
|
|
|
|
- login(login:$l,password:$p)
|
|
|
|
- }`
|
|
|
|
-let qVariables = {
|
|
|
|
- "l": login,
|
|
|
|
- "p": password
|
|
|
|
-}
|
|
|
|
-let result = await gql(query,qVariables)
|
|
|
|
-console.log(result)
|
|
|
|
-localStorage.authToken = result.data.login
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-const actionPending = name => ({type: "PROMISE" ,status:"PENDING", name})
|
|
|
|
-const actionResolved = (name,payload) => ({type: "PROMISE" ,status:"RESOLVED", name,payload})
|
|
|
|
-const actionRejected = (name,error) => ({type: "PROMISE" ,status:"REJECTED", name,error})
|
|
|
|
-
|
|
|
|
-const actionPromise = (name, promise) =>
|
|
|
|
- async dispatch => {
|
|
|
|
- dispatch(actionPending(name))
|
|
|
|
- try {
|
|
|
|
- let payload = await promise
|
|
|
|
- dispatch(actionResolved(name , payload))
|
|
|
|
- return payload
|
|
|
|
- }
|
|
|
|
- catch(error){
|
|
|
|
- dispatch(actionRejected(name , error))
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function authReducer(state, action){ //....
|
|
|
|
- if (state === undefined){
|
|
|
|
- if (!localStorage.authToken){
|
|
|
|
- return {}
|
|
|
|
- }
|
|
|
|
- action.token = localStorage.authToken
|
|
|
|
- action.type = 'LOGIN'
|
|
|
|
- // добавить в action token из localStorage, и проимитировать LOGIN
|
|
|
|
- }
|
|
|
|
- if (action.type === 'LOGIN'){
|
|
|
|
- console.log('ЛОГИН')
|
|
|
|
- localStorage.authToken = action.token
|
|
|
|
- console.log(action.token)
|
|
|
|
- function jwt_decode (token) {
|
|
|
|
- var start64Url = token.split('.')[1]
|
|
|
|
- return JSON.parse(atob(start64Url))
|
|
|
|
- }
|
|
|
|
- return {token: action.token, payload: jwt_decode(action.token)}
|
|
|
|
- }
|
|
|
|
- if (action.type === 'LOGOUT'){
|
|
|
|
- console.log('ЛОГАУТ')
|
|
|
|
- localStorage.removeItem("authToken")
|
|
|
|
- //вернуть пустой объект
|
|
|
|
- return {}
|
|
|
|
- }
|
|
|
|
- return state
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-const actionAuthLogin = token => ({type:'LOGIN', token})
|
|
|
|
-const actionAuthLogout = () => ({type:'LOGOUT'})
|
|
|
|
-const actionFullLogin = (login , password) => async dispatch => {
|
|
|
|
- let result = await dispatch(actionPromise("login",log(login,password)))
|
|
|
|
- if (result.data.login !== null){
|
|
|
|
- dispatch(actionAuthLogin(result.data.login))
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- alert ('такого пользователя не существует')
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-const actionRegister = (login,password) => async dispatch => {
|
|
|
|
- return await dispatch (actionPromise('register' , reg(login,password)))
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-const actionFullRegister = (login,password) => async dispatch => {
|
|
|
|
- let result = await dispatch (actionRegister(login,password))
|
|
|
|
- if (result.errors === undefined) {
|
|
|
|
- await dispatch (actionFullLogin(login,password))
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- alert("Такой пользователь уже есть")
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-let reducers = {
|
|
|
|
- promise:promiseReducer,
|
|
|
|
- auth:authReducer
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-const store = createStore(combineReducers(reducers), applyMiddleware(thunk))
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-const LoginForm = ({ onLogin }) => {
|
|
|
|
- const [login, setLogin] = useState("");
|
|
|
|
- const [password, setPassword] = useState("");
|
|
|
|
- //надо тип инпуту
|
|
|
|
- //надо проверку на пустоту инпутов и запрет кнопки (disabled)
|
|
|
|
- //надо при кнопке отправить в onLogin login и пароль. onLogin - это функция-колбэк
|
|
|
|
- return (
|
|
|
|
- <>
|
|
|
|
- <input value={login} onChange={(e) => setLogin(e.target.value)} />
|
|
|
|
- <input
|
|
|
|
- type="password"
|
|
|
|
- value={password}
|
|
|
|
- onChange={(e) => setPassword(e.target.value)}
|
|
|
|
- />
|
|
|
|
- <button
|
|
|
|
- onClick={() => onLogin(login, password)}
|
|
|
|
- disabled={!login || !password}
|
|
|
|
- >
|
|
|
|
- Sign in
|
|
|
|
- </button>
|
|
|
|
-
|
|
|
|
- </>
|
|
|
|
- );
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-const ConnectedLoginForm = connect(null, {onLogin: actionAuthLogin})(LoginForm)
|
|
|
|
-
|
|
|
|
-const unsubscribe = store.subscribe(() => console.log('result here',store.getState()))
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-const NickName = ({nick}) => {
|
|
|
|
- return (
|
|
|
|
- <p></p>,
|
|
|
|
- <a href = '#'>{nick || 'anon'}</a>
|
|
|
|
- )
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- const ConnectedNick = connect(state => ({nick:state?.auth?.payload?.sub?.login }))(NickName)
|
|
|
|
-
|
|
|
|
- const LogOut = connect ((state) => ({children:'Logout' , disabled:!state.auth.token }) , ({onClick:actionAuthLogout}))('button')
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-function App() {
|
|
|
|
- return (
|
|
|
|
- <div className="App">
|
|
|
|
- <Provider store = {store}>
|
|
|
|
- <ConnectedNick/> <br/>
|
|
|
|
- <ConnectedLoginForm/>
|
|
|
|
- <LogOut/>
|
|
|
|
- {/* <Form/> */}
|
|
|
|
- </Provider>
|
|
|
|
-
|
|
|
|
- </div>
|
|
|
|
- );
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-export default App;
|
|
|