Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
products_lesson_front
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Pavel Mishakov
products_lesson_front
Commits
07b61617
Commit
07b61617
authored
Mar 25, 2023
by
Pavel Mishakov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add token check and Private route
parent
db6fb5cb
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
65 additions
and
53 deletions
+65
-53
App.tsx
src/App.tsx
+15
-29
instance.ts
src/api/instance.ts
+10
-1
Header.tsx
src/components/Header/Header.tsx
+0
-12
ILayoutProps.ts
src/components/Layout/ILayoutProps.ts
+0
-5
Layout.tsx
src/components/Layout/Layout.tsx
+3
-3
Login.tsx
src/containers/Login/Login.tsx
+10
-2
users.slice.ts
src/store/users/users.slice.ts
+3
-1
PrivateRoute.tsx
src/utils/PrivateRoute.tsx
+24
-0
No files found.
src/App.tsx
View file @
07b61617
...
@@ -2,38 +2,24 @@ import Layout from "./components/Layout/Layout";
...
@@ -2,38 +2,24 @@ import Layout from "./components/Layout/Layout";
import
{
Routes
,
Route
}
from
"react-router-dom"
;
import
{
Routes
,
Route
}
from
"react-router-dom"
;
import
ProductFormPage
from
"./containers/ProductFormPage/ProductFormPage"
;
import
ProductFormPage
from
"./containers/ProductFormPage/ProductFormPage"
;
import
ProductsPage
from
"./containers/ProductsPage/ProductsPage"
;
import
ProductsPage
from
"./containers/ProductsPage/ProductsPage"
;
import
{
AppDispatch
,
AppState
}
from
"./store/store"
;
import
{
shallowEqual
,
useDispatch
,
useSelector
}
from
"react-redux"
;
import
{
useEffect
}
from
"react"
;
import
{
checkToken
}
from
"./store/users/users.slice"
;
import
Login
from
"./containers/Login/Login"
;
import
Login
from
"./containers/Login/Login"
;
import
Register
from
"./containers/Register/Register"
;
import
Register
from
"./containers/Register/Register"
;
import
PrivateRoute
from
"./utils/PrivateRoute"
;
const
App
=
()
=>
{
const
App
=
()
=>
{
const
dispatch
:
AppDispatch
=
useDispatch
()
const
{
isAuth
}
=
useSelector
((
state
:
AppState
)
=>
state
.
users
,
shallowEqual
)
useEffect
(()
=>
{
dispatch
(
checkToken
())
},
[])
return
(
return
(
<
Layout
>
<
Routes
>
{
isAuth
<
Route
element=
{
<
PrivateRoute
/>
}
>
?
<
Route
element=
{
<
Layout
/>
}
>
<
Routes
>
<
Route
path=
{
"/"
}
element=
{
<
h1
>
HOME
</
h1
>
}
/>
<
Route
path=
{
'/'
}
element=
{
<
h1
>
HOME
</
h1
>
}
/>
<
Route
path=
{
"/products"
}
element=
{
<
ProductsPage
/>
}
/>
<
Route
path=
{
'/products'
}
element=
{
<
ProductsPage
/>
}
/>
<
Route
path=
{
"/add-product"
}
element=
{
<
ProductFormPage
/>
}
/>
<
Route
path=
{
'/add-product'
}
element=
{
<
ProductFormPage
/>
}
/>
</
Route
>
</
Routes
>
</
Route
>
:
<
Route
path=
{
"/login"
}
element=
{
<
Login
/>
}
/>
<
Routes
>
<
Route
path=
{
"/register"
}
element=
{
<
Register
/>
}
/>
<
Route
path=
{
'/'
}
element=
{
<
Login
/>
}
/>
</
Routes
>
<
Route
path=
{
'/register'
}
element=
{
<
Register
/>
}
/>
);
</
Routes
>
};
}
</
Layout
>
)
}
export
default
App
export
default
App
;
src/api/instance.ts
View file @
07b61617
import
axios
from
"axios"
;
import
axios
,
{
InternalAxiosRequestConfig
}
from
"axios"
;
export
const
instance
=
axios
.
create
({
export
const
instance
=
axios
.
create
({
baseURL
:
import
.
meta
.
env
.
VITE_BASE_URL
baseURL
:
import
.
meta
.
env
.
VITE_BASE_URL
})
instance
.
interceptors
.
request
.
use
((
req
:
InternalAxiosRequestConfig
)
=>
{
const
token
=
localStorage
.
getItem
(
'token'
)
if
(
token
)
{
req
.
headers
.
Authorization
=
token
}
return
req
})
})
\ No newline at end of file
src/components/Header/Header.tsx
View file @
07b61617
...
@@ -5,11 +5,9 @@ import { AppState } from "../../store/store";
...
@@ -5,11 +5,9 @@ import { AppState } from "../../store/store";
import
styles
from
"./Header.module.css"
;
import
styles
from
"./Header.module.css"
;
const
Header
:
FunctionComponent
=
():
ReactElement
=>
{
const
Header
:
FunctionComponent
=
():
ReactElement
=>
{
const
{
isAuth
}
=
useSelector
((
state
:
AppState
)
=>
state
.
users
,
shallowEqual
)
return
(
return
(
<
header
className=
{
styles
.
Header
}
>
<
header
className=
{
styles
.
Header
}
>
{
isAuth
?
(
<>
<>
<
NavLink
className=
{
styles
.
Header__link
}
to=
{
"/add-product"
}
>
<
NavLink
className=
{
styles
.
Header__link
}
to=
{
"/add-product"
}
>
Add product
Add product
...
@@ -18,16 +16,6 @@ const Header: FunctionComponent = (): ReactElement => {
...
@@ -18,16 +16,6 @@ const Header: FunctionComponent = (): ReactElement => {
Products
Products
</
NavLink
>
</
NavLink
>
</>
</>
)
:
(
<>
<
NavLink
className=
{
styles
.
Header__link
}
to=
{
"/register"
}
>
Sign up
</
NavLink
>
<
NavLink
className=
{
styles
.
Header__link
}
to=
{
"/"
}
>
Login
</
NavLink
>
</>
)
}
</
header
>
</
header
>
);
);
};
};
...
...
src/components/Layout/ILayoutProps.ts
deleted
100644 → 0
View file @
db6fb5cb
import
{
ReactNode
}
from
"react"
;
export
default
interface
ILayoutProps
{
children
:
ReactNode
}
\ No newline at end of file
src/components/Layout/Layout.tsx
View file @
07b61617
import
React
,
{
FunctionComponent
,
ReactElement
}
from
"react"
;
import
React
,
{
FunctionComponent
,
ReactElement
}
from
"react"
;
import
{
Outlet
}
from
"react-router-dom"
;
import
Header
from
"../Header/Header"
;
import
Header
from
"../Header/Header"
;
import
ILayoutProps
from
"./ILayoutProps"
;
import
styles
from
'./Layout.module.css'
import
styles
from
'./Layout.module.css'
const
Layout
:
FunctionComponent
<
ILayoutProps
>
=
(
props
):
ReactElement
=>
{
const
Layout
:
FunctionComponent
=
(
):
ReactElement
=>
{
return
(
return
(
<
div
className=
{
styles
.
Layout
}
>
<
div
className=
{
styles
.
Layout
}
>
<
Header
/>
<
Header
/>
<
main
>
<
main
>
{
props
.
children
}
<
Outlet
/>
</
main
>
</
main
>
</
div
>
</
div
>
)
)
...
...
src/containers/Login/Login.tsx
View file @
07b61617
import
React
,
{
useState
}
from
'react'
import
React
,
{
use
Effect
,
use
State
}
from
'react'
import
IUserDto
from
'../../interfaces/IUserCreateDto'
import
IUserDto
from
'../../interfaces/IUserCreateDto'
import
styles
from
'./Login.module.css'
import
styles
from
'./Login.module.css'
import
{
Link
}
from
'react-router-dom'
import
{
Link
,
useLocation
,
useNavigate
}
from
'react-router-dom'
import
{
shallowEqual
,
useDispatch
,
useSelector
}
from
'react-redux'
import
{
shallowEqual
,
useDispatch
,
useSelector
}
from
'react-redux'
import
{
AppDispatch
,
AppState
}
from
'../../store/store'
import
{
AppDispatch
,
AppState
}
from
'../../store/store'
import
{
login
}
from
'../../store/users/users.slice'
import
{
login
}
from
'../../store/users/users.slice'
...
@@ -10,6 +10,9 @@ import {login} from '../../store/users/users.slice'
...
@@ -10,6 +10,9 @@ import {login} from '../../store/users/users.slice'
const
Login
:
React
.
FunctionComponent
=
():
React
.
ReactElement
=>
{
const
Login
:
React
.
FunctionComponent
=
():
React
.
ReactElement
=>
{
const
{
messageUser
}
=
useSelector
((
state
:
AppState
)
=>
state
.
users
,
shallowEqual
)
const
{
messageUser
}
=
useSelector
((
state
:
AppState
)
=>
state
.
users
,
shallowEqual
)
const
dispatch
:
AppDispatch
=
useDispatch
()
const
dispatch
:
AppDispatch
=
useDispatch
()
const
navigate
=
useNavigate
()
const
location
=
useLocation
()
const
{
isAuth
}
=
useSelector
((
state
:
AppState
)
=>
state
.
users
,
shallowEqual
)
const
[
values
,
setValues
]
=
useState
<
IUserDto
>
({
const
[
values
,
setValues
]
=
useState
<
IUserDto
>
({
username
:
''
,
username
:
''
,
password
:
''
password
:
''
...
@@ -23,6 +26,11 @@ const Login: React.FunctionComponent = (): React.ReactElement => {
...
@@ -23,6 +26,11 @@ const Login: React.FunctionComponent = (): React.ReactElement => {
e
.
preventDefault
()
e
.
preventDefault
()
dispatch
(
login
(
values
))
dispatch
(
login
(
values
))
}
}
useEffect
(()
=>
{
if
(
isAuth
)
{
navigate
(
location
.
state
?.
from
?
location
.
state
.
from
:
'/'
)
}
},
[
isAuth
])
return
(
return
(
<>
<>
<
div
>
<
div
>
...
...
src/store/users/users.slice.ts
View file @
07b61617
...
@@ -34,7 +34,7 @@ export const usersSlice = createSlice({
...
@@ -34,7 +34,7 @@ export const usersSlice = createSlice({
name
:
namespace
,
name
:
namespace
,
initialState
:
{
initialState
:
{
user
:
{}
as
IUser
,
user
:
{}
as
IUser
,
isAuth
:
false
,
isAuth
:
!!
localStorage
.
getItem
(
'token'
)
||
false
,
loadingUser
:
false
,
loadingUser
:
false
,
messageUser
:
''
messageUser
:
''
}
as
IUsersState
,
}
as
IUsersState
,
...
@@ -86,6 +86,8 @@ export const usersSlice = createSlice({
...
@@ -86,6 +86,8 @@ export const usersSlice = createSlice({
state
.
messageUser
=
action
.
payload
.
message
state
.
messageUser
=
action
.
payload
.
message
if
(
user
)
{
if
(
user
)
{
state
.
isAuth
=
true
state
.
isAuth
=
true
}
else
{
state
.
isAuth
=
false
}
}
})
})
}
}
...
...
src/utils/PrivateRoute.tsx
0 → 100644
View file @
07b61617
import
React
,
{
useEffect
}
from
'react'
import
{
shallowEqual
,
useDispatch
,
useSelector
}
from
'react-redux'
import
{
Navigate
,
Outlet
,
useLocation
}
from
'react-router-dom'
import
{
AppDispatch
,
AppState
}
from
'../store/store'
import
{
checkToken
}
from
'../store/users/users.slice'
const
PrivateRoute
:
React
.
FunctionComponent
=
():
React
.
ReactElement
=>
{
const
{
isAuth
}
=
useSelector
((
state
:
AppState
)
=>
state
.
users
,
shallowEqual
)
const
location
=
useLocation
()
const
dispatch
:
AppDispatch
=
useDispatch
()
useEffect
(()
=>
{
dispatch
(
checkToken
())
},
[
isAuth
])
return
(
isAuth
?
<
Outlet
/>
:
<
Navigate
to=
'/login'
replace
state=
{
{
from
:
location
}
}
/>
)
}
export
default
PrivateRoute
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment