|
@@ -0,0 +1,131 @@
|
|
|
|
+import { createStore, combineReducers, applyMiddleware } from "redux";
|
|
|
|
+import thunk from "redux-thunk";
|
|
|
|
+import jwt_decode from "jwt-decode";
|
|
|
|
+
|
|
|
|
+const getGQL = (url) => (query, variables = {}) => {
|
|
|
|
+ return fetch(url, {
|
|
|
|
+ method: "POST",
|
|
|
|
+ headers: {
|
|
|
|
+ Accept: "application/json",
|
|
|
|
+ "Content-Type": "application/json",
|
|
|
|
+ ...(localStorage.authToken ? { Authorization: `Bearer ${localStorage.authToken}` } : {}),
|
|
|
|
+ },
|
|
|
|
+ body: JSON.stringify({ query, variables }),
|
|
|
|
+ }).then((res) => res.json());
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+export const gql = getGQL("http://player.asmer.fs.a-level.com.ua/graphql");
|
|
|
|
+//формуляр отправляеться к ларьку и дает ,бумашку
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+export const actionAuthLogin = (jwt) => ({ type: "LOGIN", jwt })
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+export const actionAuthLogout = () => {
|
|
|
|
+
|
|
|
|
+ return { type: "LOGOUT" };//бегунок умеет разлогиневать берет бумажку и несет в ларек что б разлогинили
|
|
|
|
+};
|
|
|
|
+//экш тип действия !
|
|
|
|
+
|
|
|
|
+export const actionLogin = (login, password) => async (dispatch) => {// бегунок он берет функцию которая умеет в ларек подавать команды
|
|
|
|
+ let loginData = await dispatch(//бегунок окторый логинит
|
|
|
|
+ actionPromise(
|
|
|
|
+ "login",
|
|
|
|
+ gql(
|
|
|
|
+ `query login($login:String, $password:String){
|
|
|
|
+ login(login:$login,password:$password)
|
|
|
|
+ }`,
|
|
|
|
+ { login, password }
|
|
|
|
+ )
|
|
|
|
+ )
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ if (loginData && loginData.data.login) {
|
|
|
|
+ dispatch(actionAuthLogin(loginData.data.login));
|
|
|
|
+ // history.push(`/main/${store.getState().auth.payloadId}`);
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+export const actionPromise = (name, promise) => {//бегунок который работает с промисами
|
|
|
|
+ const actionPending = () => ({ type: "PROMISE", name, status: "PENDING", payload: null, error: null });
|
|
|
|
+ const actionResolved = (payload) => ({ type: "PROMISE", name, status: "RESOLVED", payload, error: null });
|
|
|
|
+ const actionRejected = (error) => ({ type: "PROMISE", name, status: "REJECTED", payload: null, error });
|
|
|
|
+
|
|
|
|
+ return async (dispatch) => {
|
|
|
|
+ dispatch(actionPending());
|
|
|
|
+ let payload;
|
|
|
|
+ try {
|
|
|
|
+ payload = await promise;
|
|
|
|
+ dispatch(actionResolved(payload));
|
|
|
|
+ } catch (e) {
|
|
|
|
+ dispatch(actionRejected(e));
|
|
|
|
+ }
|
|
|
|
+ return payload;
|
|
|
|
+ };
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+function authReducer(state, action) {
|
|
|
|
+ if (state === undefined) {//смотрит есть ли стейт
|
|
|
|
+ if (!localStorage.authToken) {//есть ли ключ от прошло авторизации
|
|
|
|
+ return {};//пустой ларек
|
|
|
|
+ } else {
|
|
|
|
+ action.type = "LOGIN";//делаем логиню действие логин
|
|
|
|
+ action.jwt = localStorage.authToken;//занесли токен
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (action.type === "LOGIN") {//действие логин
|
|
|
|
+ try {
|
|
|
|
+ localStorage.authToken = action.jwt;//на тот случай когда не из локалстореджа взяли информацию а пошли на сервере залогинились
|
|
|
|
+ console.log("ЛОГИН", jwt_decode(action.jwt).sub.login);//раскодироват
|
|
|
|
+ return {
|
|
|
|
+ login: true,//залогинились
|
|
|
|
+ token: action.jwt,
|
|
|
|
+ payload: jwt_decode(action.jwt).sub.login,//декодируем токен
|
|
|
|
+ payloadId: jwt_decode(action.jwt).sub.id,
|
|
|
|
+ };//это все в лорьке который отвечает за логин
|
|
|
|
+ } catch (error) {
|
|
|
|
+ localStorage.removeItem("authToken");
|
|
|
|
+ return {};
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (action.type === "LOGOUT") {
|
|
|
|
+ console.log("ЛОГАУТ");
|
|
|
|
+ localStorage.removeItem("authToken");//и локалстореджа удаляем наш токен
|
|
|
|
+ return {};
|
|
|
|
+ }
|
|
|
|
+ return state;//возвращаем пустой стейт
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+function promiseReducer(state = {}, action) {//в лорьке разные промисы лежат
|
|
|
|
+ if (["LOGOUT", "LOGIN"].includes(action.type)) return {};//если видит эти команды то очищает стейт//если польз ушел или новый все его данные нахер
|
|
|
|
+ if (action.type === "PROMISE") {//
|
|
|
|
+ const { name = "default", status, payload, error } = action;//
|
|
|
|
+ if (status) {
|
|
|
|
+ return {
|
|
|
|
+ ...state,//возвращаеться обьект , старый стейт
|
|
|
|
+ [name]: {
|
|
|
|
+ status,
|
|
|
|
+ payload: (status === "PENDING" && state[name] && state[name].payload) || payload,//добавляет в свое хранищиле новый промис// если запрос не завершенный и есть стейт с полезн информацци
|
|
|
|
+ error,
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return state;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+export const store = createStore(//хранилище создаем комбинируем из нескольких хранилищ
|
|
|
|
+ combineReducers({ auth: authReducer, promise: promiseReducer }),
|
|
|
|
+ applyMiddleware(thunk)//позволяет обробатівать я хочу пива но если пива нет я его подождую инструкция
|
|
|
|
+);//после команды стор появился гетстор субскрайб диспач
|
|
|
|
+
|
|
|
|
+store.subscribe(() => console.log(store.getState()));// при любом измении магазина в консоль вывести состояние магазина//
|