Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
I
initial_project
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
Нұрасыл Қайратұлы
initial_project
Commits
41941888
Commit
41941888
authored
Aug 13, 2024
by
Нұрасыл Қайратұлы
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update
parent
fffd782f
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
127 additions
and
50 deletions
+127
-50
.eslintrc.cjs
client/.eslintrc.cjs
+0
-25
SignIn.tsx
client/src/components/SignIn.tsx
+5
-1
AppToolbar.tsx
client/src/components/UI/AppToolbar.tsx
+25
-6
Auth.tsx
client/src/containers/Auth.tsx
+15
-2
usersSlice.ts
client/src/features/usersSlice.ts
+49
-9
user.controller.ts
server/src/controllers/user.controller.ts
+11
-1
user.repository.ts
server/src/repositories/user.repository.ts
+16
-5
user.route.ts
server/src/routes/user.route.ts
+1
-0
user.service.ts
server/src/services/user.service.ts
+5
-1
No files found.
client/.eslintrc.cjs
deleted
100644 → 0
View file @
fffd782f
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
'prettier',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 'latest',
sourceType: 'module',
// project: "./tsconfig.json",
},
plugins: ['react-refresh', 'react', '@typescript-eslint'],
rules: {
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
'react/react-in-jsx-scope': 0,
},
};
client/src/components/SignIn.tsx
View file @
41941888
...
...
@@ -14,8 +14,11 @@ export const SignIn = () => {
const
onFinish
:
FormProps
<
FieldTypeSignIn
>
[
'onFinish'
]
=
(
values
)
=>
{
dispatch
(
signInUser
(
values
))
}
const
onFinishFailed
:
FormProps
<
FieldTypeSignIn
>
[
'onFinishFailed'
]
=
(
values
)
=>
{
dispatch
(
signInUser
(
values
.
values
))
}
return
(
<
Form
name=
"basic"
...
...
@@ -24,6 +27,7 @@ export const SignIn = () => {
style=
{
{
maxWidth
:
600
}
}
initialValues=
{
{
remember
:
true
}
}
onFinish=
{
onFinish
}
onFinishFailed=
{
onFinishFailed
}
autoComplete=
"off"
>
<
Form
.
Item
<
FieldTypeSignIn
>
...
...
client/src/components/UI/AppToolbar.tsx
View file @
41941888
import
{
IUserState
}
from
'@/features/usersSlice'
;
import
{
AppBar
,
Toolbar
,
Typography
,
styled
}
from
'@mui/material'
;
import
{
IUserState
,
logout
}
from
'@/features/usersSlice'
;
import
{
useAppDispatch
}
from
'@/store/hook'
;
import
{
AppBar
,
Box
,
Button
,
Toolbar
,
Typography
,
styled
}
from
'@mui/material'
;
import
{
Link
}
from
'react-router-dom'
;
const
StyledLink
=
styled
(
Link
)(()
=>
({
color
:
'inherit'
,
textDecoration
:
'none'
,
[
'&:hover'
]:
{
color
:
'inherit'
},
[
'&:hover'
]:
{
color
:
'inherit'
}
}));
const
StyledBox
=
styled
(
Link
)(()
=>
({
width
:
'200px'
,
display
:
'flex'
,
justifyContent
:
'space-between'
,
textDecoration
:
'none'
,
color
:
'white'
}));
export
function
AppToolbar
({
user
}:
{
user
:
IUserState
|
null
})
{
const
dispatch
=
useAppDispatch
()
return
(
<>
<
AppBar
position=
"fixed"
>
...
...
@@ -16,9 +27,17 @@ export function AppToolbar({user}: {user: IUserState | null}) {
<
Typography
variant=
"h6"
component=
{
StyledLink
}
to=
{
'/'
}
>
Computer parts shop
</
Typography
>
<
Typography
variant=
"h6"
component=
{
StyledLink
}
to=
{
'/'
}
>
{
user
?.
username
}
</
Typography
>
{
user
&&
<
Box
component=
{
StyledBox
}
>
<
Typography
variant=
"h6"
component=
{
StyledLink
}
to=
{
'/'
}
>
{
user
?.
username
}
</
Typography
>
<
Button
variant=
"contained"
onClick=
{
()
=>
dispatch
(
logout
(
user
?.
id
))
}
>
Logout
</
Button
>
</
Box
>
}
</
Toolbar
>
</
AppBar
>
</>
...
...
client/src/containers/Auth.tsx
View file @
41941888
import
{
Register
}
from
"@/components/Register"
;
import
{
SignIn
}
from
"@/components/SignIn"
;
import
{
IUserError
}
from
"@/features/usersSlice"
;
import
{
useAppSelector
}
from
"@/store/hook"
;
import
{
Row
,
Tabs
,
TabsProps
}
from
"antd"
;
import
{
notification
,
Row
,
Tabs
,
TabsProps
}
from
"antd"
;
import
{
useEffect
}
from
"react"
;
import
{
useNavigate
}
from
"react-router-dom"
;
...
...
@@ -20,12 +21,24 @@ const items: TabsProps['items'] = [
export
const
Auth
=
()
=>
{
const
navigate
=
useNavigate
()
const
{
user
}
=
useAppSelector
(
state
=>
state
.
users
)
const
{
user
,
error
}
=
useAppSelector
(
state
=>
state
.
users
)
useEffect
(()
=>
{
if
(
user
)
navigate
(
'/'
)
},
[
navigate
,
user
])
useEffect
(()
=>
{
if
(
error
)
{
(
error
as
IUserError
[]).
map
(
item
=>
(
notification
.
error
({
message
:
item
.
type
,
description
:
item
.
messages
[
0
],
duration
:
2
})
))
}
},
[
error
])
return
(
<
Row
align=
{
'middle'
}
...
...
client/src/features/usersSlice.ts
View file @
41941888
...
...
@@ -2,6 +2,11 @@ import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import
{
axiosApiClient
}
from
"../helpers/axiosApiClient"
;
import
{
FieldTypeRegister
}
from
"@/components/Register"
;
import
{
FieldTypeSignIn
}
from
"@/components/SignIn"
;
import
{
isAxiosError
,
AxiosError
}
from
"axios"
;
export
interface
IUserError
{
type
:
string
messages
:
string
[]
}
export
interface
IUserState
{
id
:
string
;
...
...
@@ -12,7 +17,7 @@ export interface IUserState {
interface
State
{
user
:
IUserState
|
null
;
error
:
Error
|
null
;
error
:
IUserError
[]
|
null
|
Error
;
loading
:
boolean
;
}
...
...
@@ -24,26 +29,36 @@ const initialState: State = {
export
const
registerUser
=
createAsyncThunk
(
'users/register'
,
async
(
body
:
FieldTypeRegister
)
=>
{
async
(
body
:
FieldTypeRegister
,
{
rejectWithValue
}
)
=>
{
try
{
const
{
data
}
=
await
axiosApiClient
.
post
<
IUserState
>
(
'/user/registration'
,
body
)
localStorage
.
setItem
(
'token'
,
data
.
token
)
return
data
}
catch
(
e
)
{
throw
new
Error
((
e
as
Error
).
message
)
if
(
isAxiosError
(
e
))
{
const
error
:
AxiosError
<
any
>
=
e
return
rejectWithValue
(
error
.
response
?.
data
)
}
else
{
throw
new
Error
((
e
as
Error
).
message
)
}
}
}
)
export
const
signInUser
=
createAsyncThunk
(
'users/signInUser'
,
async
(
body
:
FieldTypeSignIn
)
=>
{
async
(
body
:
FieldTypeSignIn
,
{
rejectWithValue
}
)
=>
{
try
{
const
{
data
}
=
await
axiosApiClient
.
post
<
IUserState
>
(
'/user/signIn'
,
body
)
localStorage
.
setItem
(
'token'
,
data
.
token
)
return
data
}
catch
(
e
)
{
throw
new
Error
((
e
as
Error
).
message
)
if
(
isAxiosError
(
e
))
{
const
error
:
AxiosError
<
any
>
=
e
return
rejectWithValue
(
error
.
response
?.
data
)
}
else
{
throw
new
Error
((
e
as
Error
).
message
)
}
}
}
)
...
...
@@ -57,8 +72,18 @@ export const validateToken = createAsyncThunk(
Authorization
:
localStorage
.
getItem
(
'token'
)
}
})
console
.
log
(
data
);
return
data
}
catch
(
e
)
{
throw
new
Error
((
e
as
Error
).
message
)
}
}
)
export
const
logout
=
createAsyncThunk
(
'users/logout'
,
async
(
userId
?:
string
)
=>
{
try
{
const
{
data
}
=
await
axiosApiClient
.
get
(
`/user/logout?id=
${
userId
}
`
)
return
data
}
catch
(
e
)
{
throw
new
Error
((
e
as
Error
).
message
)
...
...
@@ -81,7 +106,7 @@ const usersSlice = createSlice(
})
.
addCase
(
registerUser
.
rejected
,
(
state
,
action
)
=>
{
state
.
loading
=
false
;
state
.
error
=
action
.
error
as
Error
;
state
.
error
=
action
.
payload
as
IUserError
[]
;
})
.
addCase
(
registerUser
.
pending
,
(
state
)
=>
{
state
.
loading
=
true
;
...
...
@@ -94,7 +119,7 @@ const usersSlice = createSlice(
})
.
addCase
(
signInUser
.
rejected
,
(
state
,
action
)
=>
{
state
.
loading
=
false
;
state
.
error
=
action
.
error
as
Error
;
state
.
error
=
action
.
payload
as
IUserError
[]
;
})
.
addCase
(
signInUser
.
pending
,
(
state
)
=>
{
state
.
loading
=
true
;
...
...
@@ -112,6 +137,21 @@ const usersSlice = createSlice(
.
addCase
(
validateToken
.
pending
,
(
state
)
=>
{
state
.
loading
=
true
;
})
// LOGOUT
.
addCase
(
logout
.
fulfilled
,
(
state
)
=>
{
state
.
user
=
null
localStorage
.
clear
()
state
.
loading
=
false
;
})
.
addCase
(
logout
.
rejected
,
(
state
,
action
)
=>
{
state
.
loading
=
false
;
state
.
error
=
action
.
error
as
Error
;
})
.
addCase
(
logout
.
pending
,
(
state
)
=>
{
state
.
user
=
null
state
.
loading
=
true
;
})
},
}
)
...
...
server/src/controllers/user.controller.ts
View file @
41941888
...
...
@@ -42,7 +42,17 @@ export class UserController {
validateToken
:
RequestHandler
=
async
(
req
,
res
):
Promise
<
void
>
=>
{
const
token
=
req
.
headers
.
authorization
const
user
=
await
this
.
service
.
validateToken
(
token
||
''
)
const
user
=
await
this
.
service
.
validateToken
(
token
)
res
.
send
(
user
)
}
logout
:
RequestHandler
=
async
(
req
,
res
):
Promise
<
void
>
=>
{
try
{
const
{
id
}
=
req
.
query
await
this
.
service
.
logout
(
parseInt
(
id
as
string
))
res
.
status
(
200
).
send
(
id
)
}
catch
(
e
)
{
res
.
status
(
500
).
send
(
e
);
}
}
}
server/src/repositories/user.repository.ts
View file @
41941888
...
...
@@ -38,11 +38,22 @@ export class UserRepo {
return
userWithoutPass
}
async
validateToken
(
token
:
string
):
Promise
<
IUser
|
null
>
{
const
user
=
await
this
.
repo
.
findOne
({
where
:
{
token
:
token
}})
if
(
!
user
)
return
null
const
userWithoutPass
=
_
.
omit
(
user
,
'password'
)
return
userWithoutPass
async
validateToken
(
token
?:
string
):
Promise
<
IUser
|
null
>
{
if
(
token
)
{
const
user
=
await
this
.
repo
.
findOne
({
where
:
{
token
:
token
}})
if
(
!
user
)
return
null
const
userWithoutPass
=
_
.
omit
(
user
,
'password'
)
return
userWithoutPass
}
else
{
return
null
}
}
async
logout
(
userId
:
number
)
{
const
user
=
await
this
.
repo
.
findOne
({
where
:
{
id
:
userId
}})
if
(
!
user
)
throw
new
Error
(
'User not have'
)
user
.
token
=
''
await
this
.
repo
.
save
(
user
)
}
}
...
...
server/src/routes/user.route.ts
View file @
41941888
...
...
@@ -16,5 +16,6 @@ export class UserRoute implements IRoute {
this
.
router
.
post
(
'/registration'
,
this
.
controller
.
registration
);
this
.
router
.
post
(
'/signIn'
,
this
.
controller
.
signIn
);
this
.
router
.
get
(
'/validateToken'
,
this
.
controller
.
validateToken
);
this
.
router
.
get
(
'/logout'
,
this
.
controller
.
logout
);
}
}
server/src/services/user.service.ts
View file @
41941888
...
...
@@ -16,7 +16,11 @@ export class UserService {
return
await
userRepo
.
registration
(
registrationUserDto
)
}
async
validateToken
(
token
:
string
)
{
async
validateToken
(
token
?
:
string
)
{
return
await
userRepo
.
validateToken
(
token
)
}
async
logout
(
userId
:
number
)
{
return
await
userRepo
.
logout
(
userId
)
}
}
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