diff --git a/src/config/pages.tsx b/src/config/pages.tsx
index 570ecc08..edcfcdfa 100644
--- a/src/config/pages.tsx
+++ b/src/config/pages.tsx
@@ -1,4 +1,5 @@
export const PAGES = {
+ home: '/home',
login: '/login',
register: '/register',
}
diff --git a/src/config/procedures.tsx b/src/config/procedures.tsx
index 257173e6..38e2a266 100644
--- a/src/config/procedures.tsx
+++ b/src/config/procedures.tsx
@@ -1,4 +1,5 @@
export const PROCEDURES = {
+ auth_user: 'auth_user',
create_user: 'create_user',
get_cities: 'get_cities',
lst_c_country: 'lst_c_country',
diff --git a/src/features/App/AuthenticatedApp.tsx b/src/features/App/AuthenticatedApp.tsx
new file mode 100644
index 00000000..b70499f4
--- /dev/null
+++ b/src/features/App/AuthenticatedApp.tsx
@@ -0,0 +1,20 @@
+import React from 'react'
+import {
+ Route,
+ Redirect,
+ Switch,
+} from 'react-router-dom'
+
+import { PAGES } from 'config'
+
+import { HomePage } from 'features/HomePage'
+
+export const AuthenticatedApp = () => (
+
+
+
+
+
+
+
+)
diff --git a/src/features/App/UnauthenticatedApp.tsx b/src/features/App/UnauthenticatedApp.tsx
new file mode 100644
index 00000000..a4e7a5a8
--- /dev/null
+++ b/src/features/App/UnauthenticatedApp.tsx
@@ -0,0 +1,25 @@
+import React from 'react'
+import {
+ Route,
+ Redirect,
+ Switch,
+} from 'react-router-dom'
+
+import { PAGES } from 'config'
+
+import { Login } from 'features/Login'
+import { Register } from 'features/Register'
+
+export const UnauthenticatedApp = () => (
+
+
+
+
+
+
+
+
+
+
+
+)
diff --git a/src/features/App/index.tsx b/src/features/App/index.tsx
index b4eb6673..f4dc79c5 100644
--- a/src/features/App/index.tsx
+++ b/src/features/App/index.tsx
@@ -1,36 +1,38 @@
import React from 'react'
-import {
- Router,
- Route,
- Redirect,
- Switch,
-} from 'react-router-dom'
+import { Router } from 'react-router-dom'
import { createBrowserHistory } from 'history'
-import { PAGES } from 'config'
+import { GlobalStores } from 'features/GlobalStores'
+import { useAuthStore } from 'features/AuthStore'
+import { Background } from 'features/Background'
import { GlobalStyles } from 'features/GlobalStyles'
import { Theme } from 'features/Theme'
-import { Login } from 'features/Login'
-import { Register } from 'features/Register'
+
+import { AuthenticatedApp } from './AuthenticatedApp'
+import { UnauthenticatedApp } from './UnauthenticatedApp'
const history = createBrowserHistory()
+const Main = () => {
+ const { token } = useAuthStore()
+ return (
+
+ {
+ token
+ ?
+ :
+ }
+
+ )
+}
+
export const App = () => (
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
)
diff --git a/src/features/AuthStore/hooks/useLogin.tsx b/src/features/AuthStore/hooks/useLogin.tsx
new file mode 100644
index 00000000..28ca33b8
--- /dev/null
+++ b/src/features/AuthStore/hooks/useLogin.tsx
@@ -0,0 +1,30 @@
+import { useHistory } from 'react-router-dom'
+
+import { PAGES } from 'config'
+import { login } from 'requests'
+import { writeToken } from 'helpers'
+
+type LoginArgs = Parameters[0]
+
+type Args = {
+ setToken: (token: string | null) => void,
+}
+
+export const useLogin = ({ setToken }: Args) => {
+ const history = useHistory()
+
+ const onSuccess = (token: string) => {
+ writeToken(token)
+ setToken(token)
+ history.replace(PAGES.home)
+ }
+
+ const onError = (message: string) => {
+ // eslint-disable-next-line no-alert
+ window.alert(message)
+ }
+
+ return async ({ email, password }: LoginArgs) => (
+ login({ email, password }).then(onSuccess, onError)
+ )
+}
diff --git a/src/features/AuthStore/hooks/useLogout.tsx b/src/features/AuthStore/hooks/useLogout.tsx
new file mode 100644
index 00000000..1ff9b376
--- /dev/null
+++ b/src/features/AuthStore/hooks/useLogout.tsx
@@ -0,0 +1,26 @@
+import { useHistory } from 'react-router-dom'
+
+import { PAGES } from 'config'
+import { removeToken } from 'helpers'
+// import { logout } from 'requests'
+
+// временная заглушка запроса
+const logout = () => Promise.resolve()
+
+type Args = {
+ setToken: (token: string | null) => void,
+}
+
+export const useLogout = ({ setToken }: Args) => {
+ const history = useHistory()
+
+ const onSuccess = () => {
+ removeToken()
+ setToken(null)
+ history.replace(PAGES.login)
+ }
+
+ return async () => (
+ logout().then(onSuccess)
+ )
+}
diff --git a/src/features/AuthStore/hooks/useRegister.tsx b/src/features/AuthStore/hooks/useRegister.tsx
new file mode 100644
index 00000000..732d83d3
--- /dev/null
+++ b/src/features/AuthStore/hooks/useRegister.tsx
@@ -0,0 +1,23 @@
+import { useHistory } from 'react-router-dom'
+
+import { PAGES } from 'config'
+import { register } from 'requests'
+
+type Args = Parameters[0]
+
+export const useRegister = () => {
+ const history = useHistory()
+
+ const goToLoginPage = () => {
+ history.replace(PAGES.login)
+ }
+
+ const showError = (message: string) => {
+ // eslint-disable-next-line no-alert
+ window.alert(message)
+ }
+
+ return async (args: Args) => (
+ register(args).then(goToLoginPage, showError)
+ )
+}
diff --git a/src/features/AuthStore/index.tsx b/src/features/AuthStore/index.tsx
new file mode 100644
index 00000000..01b76d01
--- /dev/null
+++ b/src/features/AuthStore/index.tsx
@@ -0,0 +1,43 @@
+import type { ReactNode } from 'react'
+import React, {
+ createContext,
+ useContext,
+ useState,
+} from 'react'
+
+import { readToken } from 'helpers'
+
+import { useLogin } from './hooks/useLogin'
+import { useLogout } from './hooks/useLogout'
+import { useRegister } from './hooks/useRegister'
+
+type Auth = {
+ login: ReturnType,
+ logout: ReturnType,
+ register: ReturnType,
+ token: string | null,
+}
+
+const AuthContext = createContext({} as Auth)
+
+type Props = {
+ children: ReactNode,
+}
+
+export const AuthStore = ({ children }: Props) => {
+ const [token, setToken] = useState(readToken())
+ const login = useLogin({ setToken })
+ const logout = useLogout({ setToken })
+ const register = useRegister()
+
+ const auth = {
+ login,
+ logout,
+ register,
+ token,
+ }
+
+ return {children}
+}
+
+export const useAuthStore = () => useContext(AuthContext)
diff --git a/src/features/GlobalStores/index.tsx b/src/features/GlobalStores/index.tsx
new file mode 100644
index 00000000..5690cd0f
--- /dev/null
+++ b/src/features/GlobalStores/index.tsx
@@ -0,0 +1,14 @@
+import React, { ReactNode } from 'react'
+
+import { AuthStore } from 'features/AuthStore'
+
+type Props = {
+ children: ReactNode,
+}
+
+// аутентификация, лексики и другие глобальные сторы
+export const GlobalStores = ({ children }: Props) => (
+
+ {children}
+
+)
diff --git a/src/features/HomePage/index.tsx b/src/features/HomePage/index.tsx
new file mode 100644
index 00000000..d046b534
--- /dev/null
+++ b/src/features/HomePage/index.tsx
@@ -0,0 +1,33 @@
+import React from 'react'
+
+import styled from 'styled-components/macro'
+
+import { Logo } from 'features/Logo'
+import { CenterBlock } from 'features/Login/styled'
+import { useAuthStore } from 'features/AuthStore'
+
+// временные компоненты
+const TempContainer = styled.div`
+ margin-top: 50px;
+ color: white;
+ font-size: 20px;
+ display: flex;
+ flex-direction: column;
+`
+
+const TempPageTitle = styled.span`
+ margin: 20px 0;
+`
+
+export const HomePage = () => {
+ const { logout } = useAuthStore()
+ return (
+
+
+
+ HOME PAGE
+
+
+
+ )
+}
diff --git a/src/features/Login/hooks.tsx b/src/features/Login/hooks.tsx
new file mode 100644
index 00000000..d98139c9
--- /dev/null
+++ b/src/features/Login/hooks.tsx
@@ -0,0 +1,26 @@
+import type { FormEvent } from 'react'
+
+import trim from 'lodash/trim'
+
+import { useAuthStore } from 'features/AuthStore'
+import { formIds } from 'features/Register/components/RegistrationStep/config'
+
+const readFormValue = (event: FormEvent) => (
+ (fieldName: string) => trim(event.currentTarget[fieldName]?.value)
+)
+
+export const useForm = () => {
+ const { login } = useAuthStore()
+
+ const handleSubmit = async (event: FormEvent) => {
+ event.preventDefault()
+
+ const readFieldValue = readFormValue(event)
+ const email = readFieldValue(formIds.email)
+ const password = readFieldValue(formIds.password)
+
+ login({ email, password })
+ }
+
+ return { handleSubmit }
+}
diff --git a/src/features/Login/index.tsx b/src/features/Login/index.tsx
index 972d5af5..3f5ebe5e 100644
--- a/src/features/Login/index.tsx
+++ b/src/features/Login/index.tsx
@@ -2,13 +2,11 @@ import React from 'react'
import { PAGES } from 'config'
-import { Background } from 'features/Background'
import { Logo } from 'features/Logo'
-import {
- Input,
- ButtonSolid,
-} from 'features/Common'
+import { Input, ButtonSolid } from 'features/Common'
+import { formIds } from 'features/Register/components/RegistrationStep/config'
+import { useForm } from './hooks'
import {
BlockTitle,
CenterBlock,
@@ -19,35 +17,37 @@ import {
const labelWidth = 60
-export const Login = () => (
-
+export const Login = () => {
+ const { handleSubmit } = useForm()
+
+ return (
-
-
-)
+ )
+}
diff --git a/src/features/Register/components/RegistrationStep/hooks/useForm.tsx b/src/features/Register/components/RegistrationStep/hooks/useForm.tsx
index 94f64dcf..2363ff3a 100644
--- a/src/features/Register/components/RegistrationStep/hooks/useForm.tsx
+++ b/src/features/Register/components/RegistrationStep/hooks/useForm.tsx
@@ -1,12 +1,9 @@
import type { FormEvent } from 'react'
import { useEffect } from 'react'
-import { useHistory } from 'react-router-dom'
import trim from 'lodash/trim'
-import { PAGES } from 'config'
-import { register } from 'requests'
-
+import { useAuthStore } from 'features/AuthStore'
import { isValidEmail } from 'features/Register/helpers/isValidEmail'
import { formIds } from '../config'
@@ -18,7 +15,7 @@ const readFormValue = (event: FormEvent) => (
)
export const useForm = () => {
- const history = useHistory()
+ const { register } = useAuthStore()
const {
countries,
onCountrySelect,
@@ -44,15 +41,6 @@ export const useForm = () => {
resetCities,
])
- const goToLoginPage = () => {
- history.replace(PAGES.login)
- }
-
- const showError = (message: string) => {
- // eslint-disable-next-line no-alert
- window.alert(message)
- }
-
const getCityParams = () => {
if (selectedCity) return { cityId: selectedCity.id }
return { city: cityQuery }
@@ -86,7 +74,7 @@ export const useForm = () => {
phone,
postalCode,
region,
- }).then(goToLoginPage, showError)
+ })
}
}
diff --git a/src/features/Register/index.tsx b/src/features/Register/index.tsx
index 02a5ba4d..a595e1a1 100644
--- a/src/features/Register/index.tsx
+++ b/src/features/Register/index.tsx
@@ -3,7 +3,6 @@ import { Route } from 'react-router'
import { PAGES } from 'config'
-import { Background } from 'features/Background'
import { Logo } from 'features/Logo'
import { CenterBlock } from 'features/Login/styled'
@@ -12,18 +11,16 @@ import { CardStep } from './components/CardStep'
import { SubscriptionStep } from './components/SubscriptionsStep'
export const Register = () => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
)
diff --git a/src/helpers/callApi/getRequestConfig.tsx b/src/helpers/callApi/getRequestConfig.tsx
index e9eb7f3f..14ebafab 100644
--- a/src/helpers/callApi/getRequestConfig.tsx
+++ b/src/helpers/callApi/getRequestConfig.tsx
@@ -1,6 +1,6 @@
import { AUTH_KEYS } from 'config'
+import { readToken } from 'helpers'
-import { loadIdToken } from './loadIdToken'
import { TRequestConfig } from './types'
export const getRequestConfig = (
@@ -19,7 +19,7 @@ export const getRequestConfig = (
requestConfig.headers.set('Content-Type', 'application/json')
}
- const token = loadIdToken()
+ const token = readToken()
if (token) {
requestConfig.headers.set(AUTH_KEYS.headerToken, token)
diff --git a/src/helpers/callApi/loadIdToken.tsx b/src/helpers/callApi/loadIdToken.tsx
deleted file mode 100644
index c1f70feb..00000000
--- a/src/helpers/callApi/loadIdToken.tsx
+++ /dev/null
@@ -1 +0,0 @@
-export const loadIdToken = () => localStorage.getItem('id_token')
diff --git a/src/helpers/index.tsx b/src/helpers/index.tsx
index 1ba6128d..1c31f046 100644
--- a/src/helpers/index.tsx
+++ b/src/helpers/index.tsx
@@ -1,2 +1,3 @@
export * from './callApi'
export * from './callApi/getResponseData'
+export * from './token'
diff --git a/src/helpers/token/index.tsx b/src/helpers/token/index.tsx
new file mode 100644
index 00000000..06eb165b
--- /dev/null
+++ b/src/helpers/token/index.tsx
@@ -0,0 +1,13 @@
+const TOKEN_KEY = 'token'
+
+export const readToken = () => (
+ localStorage.getItem(TOKEN_KEY)
+)
+
+export const writeToken = (token: string) => (
+ localStorage.setItem(TOKEN_KEY, token)
+)
+
+export const removeToken = () => (
+ localStorage.removeItem(TOKEN_KEY)
+)
diff --git a/src/requests/login.tsx b/src/requests/login.tsx
index 627dbbf4..dd83c27f 100644
--- a/src/requests/login.tsx
+++ b/src/requests/login.tsx
@@ -1 +1,51 @@
-export const login = () => {}
+import { DATA_URL, PROCEDURES } from 'config'
+import { callApi, writeToken } from 'helpers'
+
+const proc = PROCEDURES.auth_user
+
+const statusCodes = {
+ ACCOUNT_EXPIRED: 5,
+ EMAIL_NOT_FOUND: 2,
+ INVALID_CREDENTIALS: 3,
+ SUCCESS: 1,
+ USER_REMOVED_OR_BLOCKED: 4,
+} as const
+
+type StatusCodes = typeof statusCodes[keyof typeof statusCodes]
+
+type Response = {
+ _p_status: StatusCodes,
+ _p_token: string,
+}
+
+type Args = {
+ email: string,
+ password: string,
+}
+
+export const login = async ({
+ email,
+ password,
+}: Args) => {
+ const config = {
+ body: {
+ params: {
+ _p_email: email,
+ _p_password: password,
+ },
+ proc,
+ },
+ }
+
+ const response: Response = await callApi({
+ config,
+ url: DATA_URL,
+ })
+
+ if (response._p_status === statusCodes.SUCCESS) {
+ writeToken(response._p_token)
+ return Promise.resolve(response._p_token)
+ }
+
+ return Promise.reject(response._p_status)
+}