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 ( <> setLogin(e.target.value)} /> setPassword(e.target.value)} /> > ); }; const ConnectedLoginForm = connect(null, {onLogin: actionAuthLogin})(LoginForm) const unsubscribe = store.subscribe(() => console.log('result here',store.getState())) const NickName = ({nick}) => { return (
, {nick || 'anon'} ) } 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 (