diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index ff53e248..00000000 --- a/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -src/types/* -src/api/operations/**/*.tsx -src/react-app-env.d.ts -src/serviceWorker.ts diff --git a/.storybook/main.js b/.storybook/main.js index ab7f9c40..8ef6cf34 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -3,12 +3,10 @@ module.exports = { addons: [ '@storybook/addon-actions', '@storybook/addon-links', - '@storybook/preset-create-react-app', - { - name: "@storybook/addon-docs", - options: { - configureJSX: true, - }, - }, + '@storybook/addon-docs', + 'storybook-addon-styled-component-theme/dist/register', ], -}; + presets: [ + '@storybook/preset-create-react-app', + ] +} diff --git a/.storybook/preview-head.html b/.storybook/preview-head.html new file mode 100644 index 00000000..ae1b4941 --- /dev/null +++ b/.storybook/preview-head.html @@ -0,0 +1,47 @@ + + diff --git a/.storybook/preview.js b/.storybook/preview.js new file mode 100644 index 00000000..dd25eb0c --- /dev/null +++ b/.storybook/preview.js @@ -0,0 +1,7 @@ +import { addDecorator } from '@storybook/react' +import { withThemesProvider } from 'storybook-addon-styled-component-theme' + +import { lightTheme, darkTheme } from '../src/features/Theme/config' + +const themes = [darkTheme, lightTheme] +addDecorator(withThemesProvider(themes)) diff --git a/codegen.yml b/codegen.yml deleted file mode 100644 index 7801e848..00000000 --- a/codegen.yml +++ /dev/null @@ -1,22 +0,0 @@ -overwrite: true -schema: '' -documents: src/api/operations/**/*.graphql -generates: - src/types/index.tsx: - plugins: - - typescript - src/: - preset: - near-operation-file - presetConfig: - extension: .tsx - baseTypesPath: types - plugins: - - typescript-operations - - typescript-react-apollo - config: - withComponent: false - withHOC: false - withHooks: true -config: - typesPrefix: T diff --git a/commitlint.config.js b/commitlint.config.js index c0dfabc3..df2285be 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -2,7 +2,7 @@ const Configuration = { extends: ['@commitlint/config-conventional'], /** Any rules defined here will override rules from - * @commitlint/config-conventional **/ + * @commitlint/config-conventional */ rules: { 'body-max-length': [2, 'always', 120], 'body-min-length': [2, 'always', 3], diff --git a/package.json b/package.json index 226771b8..54a5925e 100644 --- a/package.json +++ b/package.json @@ -3,22 +3,16 @@ "version": "0.1.0", "private": true, "scripts": { - "prestart ": "yarn generate", "start": "react-scripts start", "build": "GENERATE_SOURCEMAP=false react-scripts build && gzipper --verbose ./build", "test": "react-scripts test --testMatch '**/__tests__/*' --passWithNoTests --watchAll=false", "test:watch": "react-scripts test --testMatch '**/__tests__/*'", "eject": "react-scripts eject", - "generate": "graphql-codegen --config codegen.yml", "lint": "eslint 'src/**/*.{ts,tsx}'", "storybook": "start-storybook -p 9009 -s public", "build-storybook": "build-storybook -s public" }, "dependencies": { - "@apollo/react-common": "^3.1.4", - "@apollo/react-hooks": "^3.1.5", - "apollo-boost": "^0.4.9", - "graphql": "^15.0.0", "lodash": "^4.17.15", "react": "^16.13.1", "react-dom": "^16.13.1", @@ -27,12 +21,6 @@ "devDependencies": { "@commitlint/cli": "^8.3.5", "@commitlint/config-conventional": "^8.3.4", - "@graphql-codegen/cli": "1.15.0", - "@graphql-codegen/import-types-preset": "^1.15.0", - "@graphql-codegen/near-operation-file-preset": "^1.15.0", - "@graphql-codegen/typescript": "1.15.0", - "@graphql-codegen/typescript-operations": "1.15.0", - "@graphql-codegen/typescript-react-apollo": "1.15.0", "@storybook/addon-actions": "^5.3.19", "@storybook/addon-docs": "^5.3.19", "@storybook/addon-links": "^5.3.19", @@ -62,6 +50,7 @@ "gzipper": "^3.7.0", "husky": "^4.2.5", "lint-staged": "^10.2.7", + "storybook-addon-styled-component-theme": "^1.3.0", "ts-loader": "^7.0.5", "typescript": "^3.9.3" }, diff --git a/src/api/operations/User/queries.graphql b/src/api/operations/User/queries.graphql deleted file mode 100644 index 14ec1c2c..00000000 --- a/src/api/operations/User/queries.graphql +++ /dev/null @@ -1,8 +0,0 @@ -query User { - __schema { - types { - name - kind - } - } -} diff --git a/src/api/operations/User/queries.tsx b/src/api/operations/User/queries.tsx deleted file mode 100644 index bbbcc5b7..00000000 --- a/src/api/operations/User/queries.tsx +++ /dev/null @@ -1,3 +0,0 @@ -// autgenerated using https://graphql-code-generator.com/ - -export {} diff --git a/src/config/authKeys.tsx b/src/config/authKeys.tsx new file mode 100644 index 00000000..a6199593 --- /dev/null +++ b/src/config/authKeys.tsx @@ -0,0 +1,7 @@ +export const AUTH_KEYS = { + authUser: 'AuthUser', + backLocation: 'backLocation', + cookieToken: 'token', + headerToken: 'x-auth-token', + idToken: 'id_token', +} diff --git a/src/config/index.tsx b/src/config/index.tsx index 49800c7a..bf81f61f 100644 --- a/src/config/index.tsx +++ b/src/config/index.tsx @@ -1 +1,3 @@ export * from './routes' +export * from './pages' +export * from './authKeys' diff --git a/src/config/pages.tsx b/src/config/pages.tsx new file mode 100644 index 00000000..f960c655 --- /dev/null +++ b/src/config/pages.tsx @@ -0,0 +1,3 @@ +export const PAGES = { + login: '/login', +} diff --git a/src/config/routes.tsx b/src/config/routes.tsx index 2f03b423..7cc14d50 100644 --- a/src/config/routes.tsx +++ b/src/config/routes.tsx @@ -1,2 +1,2 @@ export const API_ROOT = '' -export const GRAPHQL = `${API_ROOT}/graphql` +export const DATA_URL = `${API_ROOT}/data` diff --git a/src/helpers/callApi/checkStatus.tsx b/src/helpers/callApi/checkStatus.tsx new file mode 100644 index 00000000..4b3b206a --- /dev/null +++ b/src/helpers/callApi/checkStatus.tsx @@ -0,0 +1,7 @@ +export const checkStatus = (response: Response) => { + if (!response.ok) { + return Promise.reject(new Error(response.statusText)) + } + + return Promise.resolve(response) +} diff --git a/src/helpers/callApi/clearUserAuthInfo.tsx b/src/helpers/callApi/clearUserAuthInfo.tsx new file mode 100644 index 00000000..1af1eeed --- /dev/null +++ b/src/helpers/callApi/clearUserAuthInfo.tsx @@ -0,0 +1,6 @@ +import { AUTH_KEYS } from 'config' + +export const clearUserAuthInfo = () => { + localStorage.removeItem(AUTH_KEYS.idToken) + localStorage.removeItem(AUTH_KEYS.authUser) +} diff --git a/src/helpers/callApi/getRequestConfig.tsx b/src/helpers/callApi/getRequestConfig.tsx new file mode 100644 index 00000000..e9eb7f3f --- /dev/null +++ b/src/helpers/callApi/getRequestConfig.tsx @@ -0,0 +1,29 @@ +import { AUTH_KEYS } from 'config' + +import { loadIdToken } from './loadIdToken' +import { TRequestConfig } from './types' + +export const getRequestConfig = ( + config: TRequestConfig, + signal?: AbortSignal, +) => { + const requestConfig = { + ...config, + headers: config.headers || new Headers(), + method: config.method || 'POST', + signal, + } + + if (config.body) { + requestConfig.body = JSON.stringify(config.body) + requestConfig.headers.set('Content-Type', 'application/json') + } + + const token = loadIdToken() + + if (token) { + requestConfig.headers.set(AUTH_KEYS.headerToken, token) + } + + return requestConfig +} diff --git a/src/helpers/callApi/getResponseData.tsx b/src/helpers/callApi/getResponseData.tsx new file mode 100644 index 00000000..149ace17 --- /dev/null +++ b/src/helpers/callApi/getResponseData.tsx @@ -0,0 +1,3 @@ +export const getResponseData = (proc: string) => (response: any) => ( + response?.data?.[0]?.[proc] +) diff --git a/src/helpers/callApi/index.tsx b/src/helpers/callApi/index.tsx new file mode 100644 index 00000000..93cd59a0 --- /dev/null +++ b/src/helpers/callApi/index.tsx @@ -0,0 +1,36 @@ +import { TCallApi } from './types' +import { parseJSON } from './parseJSON' +import { checkStatus } from './checkStatus' +import { getRequestConfig } from './getRequestConfig' +import { logoutIfUnauthorized } from './logoutIfUnauthorized' + +export const callApiBase = ({ + abortSignal, + config, + url, +}: TCallApi) => { + const requestConfig = getRequestConfig(config, abortSignal) + + // eslint-disable-next-line no-console + console.log( + '%c callApi from module - config ', + 'color: white; background-color: #95B46A', + config, + ) + + return fetch(url, requestConfig) +} + +export const callApi = ({ + abortSignal, + config, + url, +}: TCallApi) => ( + callApiBase({ + abortSignal, + config, + url, + }).then(checkStatus) + .then(parseJSON) + .catch(logoutIfUnauthorized) +) diff --git a/src/helpers/callApi/loadIdToken.tsx b/src/helpers/callApi/loadIdToken.tsx new file mode 100644 index 00000000..c1f70feb --- /dev/null +++ b/src/helpers/callApi/loadIdToken.tsx @@ -0,0 +1 @@ +export const loadIdToken = () => localStorage.getItem('id_token') diff --git a/src/helpers/callApi/logoutIfUnauthorized.tsx b/src/helpers/callApi/logoutIfUnauthorized.tsx new file mode 100644 index 00000000..a666d742 --- /dev/null +++ b/src/helpers/callApi/logoutIfUnauthorized.tsx @@ -0,0 +1,22 @@ +import { AUTH_KEYS, PAGES } from 'config' + +import { removeCookie } from './removeCookie' +import { clearUserAuthInfo } from './clearUserAuthInfo' + +export const logoutIfUnauthorized = (error: Error) => { + if (error.message === 'Unauthorized') { + clearUserAuthInfo() + removeCookie(AUTH_KEYS.cookieToken) + + const { pathname } = window.location + + if (pathname !== PAGES.login) { + localStorage.setItem(AUTH_KEYS.backLocation, pathname) + window.location.pathname = PAGES.login + } + } + + // eslint-disable-next-line no-console + console.error(error) + return Promise.reject(error) +} diff --git a/src/helpers/callApi/parseJSON.tsx b/src/helpers/callApi/parseJSON.tsx new file mode 100644 index 00000000..12709130 --- /dev/null +++ b/src/helpers/callApi/parseJSON.tsx @@ -0,0 +1 @@ +export const parseJSON = (response: Response) => response.json() diff --git a/src/helpers/callApi/removeCookie.tsx b/src/helpers/callApi/removeCookie.tsx new file mode 100644 index 00000000..4118169c --- /dev/null +++ b/src/helpers/callApi/removeCookie.tsx @@ -0,0 +1,11 @@ +export const removeCookie = ( + name: string, + domain: string = '.instatscout.com', +) => { + document.cookie = ` + ${name}=; + expires='Thu, 01 Jan 1970 00:00:00 UTC'; + path=/; + domain=${domain} + ` +} diff --git a/src/helpers/callApi/types.tsx b/src/helpers/callApi/types.tsx new file mode 100644 index 00000000..fe2212b3 --- /dev/null +++ b/src/helpers/callApi/types.tsx @@ -0,0 +1,11 @@ +export type TRequestConfig = { + body?: any, + headers?: Headers, + method?: string, +} + +export type TCallApi = { + abortSignal?: AbortSignal, + config: TRequestConfig, + url: string, +} diff --git a/src/helpers/index.tsx b/src/helpers/index.tsx index 336ce12b..8842e651 100644 --- a/src/helpers/index.tsx +++ b/src/helpers/index.tsx @@ -1 +1 @@ -export {} +export * from './callApi' diff --git a/src/index.tsx b/src/index.tsx index 93c34645..519bd6e4 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,22 +1,13 @@ import React from 'react' import ReactDOM from 'react-dom' -import ApolloClient from 'apollo-boost' -import { ApolloProvider } from '@apollo/react-hooks' -import { GRAPHQL } from 'config' import { App } from 'features/App' import * as serviceWorker from './serviceWorker' -const client = new ApolloClient({ - uri: GRAPHQL, -}) - ReactDOM.render( - - - + , document.getElementById('root'), ) diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts index 6431bc5f..d3e30f32 100644 --- a/src/react-app-env.d.ts +++ b/src/react-app-env.d.ts @@ -1 +1,2 @@ +// eslint-disable-next-line spaced-comment /// diff --git a/src/api/requests/index.tsx b/src/requests/index.tsx similarity index 100% rename from src/api/requests/index.tsx rename to src/requests/index.tsx diff --git a/src/api/requests/login.tsx b/src/requests/login.tsx similarity index 100% rename from src/api/requests/login.tsx rename to src/requests/login.tsx diff --git a/src/serviceWorker.ts b/src/serviceWorker.ts index 425d17b1..5656739b 100644 --- a/src/serviceWorker.ts +++ b/src/serviceWorker.ts @@ -1,3 +1,4 @@ +/* eslint-disable */ // This optional code is used to register a service worker. // register() is not called by default. diff --git a/src/types/index.tsx b/src/types/index.tsx deleted file mode 100644 index bbbcc5b7..00000000 --- a/src/types/index.tsx +++ /dev/null @@ -1,3 +0,0 @@ -// autgenerated using https://graphql-code-generator.com/ - -export {}