diff --git a/src/api/operations/User/operation.graphql b/src/api/operations/User/operation.graphql
new file mode 100644
index 00000000..14ec1c2c
--- /dev/null
+++ b/src/api/operations/User/operation.graphql
@@ -0,0 +1,8 @@
+query User {
+ __schema {
+ types {
+ name
+ kind
+ }
+ }
+}
diff --git a/src/api/operations/User/operation.tsx b/src/api/operations/User/operation.tsx
new file mode 100644
index 00000000..bbbcc5b7
--- /dev/null
+++ b/src/api/operations/User/operation.tsx
@@ -0,0 +1,3 @@
+// autgenerated using https://graphql-code-generator.com/
+
+export {}
diff --git a/src/api/requests/index.tsx b/src/api/requests/index.tsx
new file mode 100644
index 00000000..d4389750
--- /dev/null
+++ b/src/api/requests/index.tsx
@@ -0,0 +1 @@
+export * from './login'
diff --git a/src/api/requests/login.tsx b/src/api/requests/login.tsx
new file mode 100644
index 00000000..627dbbf4
--- /dev/null
+++ b/src/api/requests/login.tsx
@@ -0,0 +1 @@
+export const login = () => {}
diff --git a/src/config/index.tsx b/src/config/index.tsx
new file mode 100644
index 00000000..49800c7a
--- /dev/null
+++ b/src/config/index.tsx
@@ -0,0 +1 @@
+export * from './routes'
diff --git a/src/config/routes.tsx b/src/config/routes.tsx
new file mode 100644
index 00000000..ff4452e0
--- /dev/null
+++ b/src/config/routes.tsx
@@ -0,0 +1 @@
+export const API_ROOT = ''
diff --git a/src/features/Login/index.tsx b/src/features/Login/index.tsx
new file mode 100644
index 00000000..741eb3d8
--- /dev/null
+++ b/src/features/Login/index.tsx
@@ -0,0 +1,7 @@
+import React from 'react'
+
+export const Login = () => (
+
+ Login page
+
+)
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..c48925f4
--- /dev/null
+++ b/src/helpers/callApi/clearUserAuthInfo.tsx
@@ -0,0 +1,4 @@
+export const clearUserAuthInfo = () => {
+ localStorage.removeItem('id_token')
+ localStorage.removeItem('AuthUser')
+}
diff --git a/src/helpers/callApi/getRequestConfig.tsx b/src/helpers/callApi/getRequestConfig.tsx
new file mode 100644
index 00000000..8bbf113e
--- /dev/null
+++ b/src/helpers/callApi/getRequestConfig.tsx
@@ -0,0 +1,35 @@
+import isString from 'lodash/isString'
+
+import { loadIdToken } from './loadIdToken'
+import { TRequestAbortController, TRequestConfig } from './types'
+
+export const getRequestConfig = (
+ config: TRequestConfig,
+ abortController?: TRequestAbortController,
+) => {
+ const requestConfig = {
+ method: 'POST',
+ ...config,
+ headers: new Headers(),
+ }
+
+ if (config.body && !isString(config.body)) {
+ requestConfig.body = JSON.stringify(config.body)
+ }
+
+ if (config.body) {
+ requestConfig.headers.set('Content-Type', 'application/json')
+ }
+
+ if (abortController) {
+ requestConfig.signal = abortController.signal
+ }
+
+ const token = loadIdToken()
+
+ if (token) {
+ requestConfig.headers.set('x-auth-token', 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..00a38273
--- /dev/null
+++ b/src/helpers/callApi/index.tsx
@@ -0,0 +1,42 @@
+import { TCallApi } from './types'
+import { parseJSON } from './parseJSON'
+import { checkStatus } from './checkStatus'
+import { removeCookie } from './removeCookie'
+import { clearUserAuthInfo } from './clearUserAuthInfo'
+import { getRequestConfig } from './getRequestConfig'
+
+export const callApi = ({
+ abortController,
+ config,
+ url,
+}: TCallApi) => {
+ const requestConfig = getRequestConfig(config, abortController)
+
+ // eslint-disable-next-line no-console
+ console.log(
+ '%c callApi from module - config ',
+ 'color: white; background-color: #95B46A',
+ config,
+ )
+
+ return fetch(url, requestConfig)
+ .then(checkStatus)
+ .then(parseJSON)
+ .catch((error) => {
+ if (error.message === 'Unauthorized') {
+ clearUserAuthInfo()
+ removeCookie('token')
+
+ if (window.location.pathname !== '/login') {
+ localStorage.setItem('backLocation', window.location.pathname)
+ window.location.pathname = '/login'
+ }
+ }
+
+ // eslint-disable-next-line no-console
+ console.error(error)
+ return Promise.reject(error)
+ })
+}
+
+export { getResponseData } from './getResponseData'
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/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..cb2b105a
--- /dev/null
+++ b/src/helpers/callApi/types.tsx
@@ -0,0 +1,14 @@
+export type TRequestConfig = {
+ [key: string]: any,
+ body?: any,
+ headers?: Headers,
+ signal?: any,
+}
+
+export type TRequestAbortController = AbortController | null
+
+export type TCallApi = {
+ abortController?: TRequestAbortController,
+ config: TRequestConfig,
+ url: string,
+}
diff --git a/src/helpers/index.tsx b/src/helpers/index.tsx
new file mode 100644
index 00000000..8842e651
--- /dev/null
+++ b/src/helpers/index.tsx
@@ -0,0 +1 @@
+export * from './callApi'
diff --git a/src/hooks/index.tsx b/src/hooks/index.tsx
new file mode 100644
index 00000000..cd448150
--- /dev/null
+++ b/src/hooks/index.tsx
@@ -0,0 +1 @@
+export * from './usePageId'
diff --git a/src/hooks/usePageId.tsx b/src/hooks/usePageId.tsx
new file mode 100644
index 00000000..7d6a8899
--- /dev/null
+++ b/src/hooks/usePageId.tsx
@@ -0,0 +1 @@
+export const usePageId = () => {}
diff --git a/src/types/index.tsx b/src/types/index.tsx
new file mode 100644
index 00000000..bbbcc5b7
--- /dev/null
+++ b/src/types/index.tsx
@@ -0,0 +1,3 @@
+// autgenerated using https://graphql-code-generator.com/
+
+export {}