Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
Toggle navigation
This project
Loading...
Sign in
hfpp2012
/
merng
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 723d4202
authored
Nov 09, 2019
by
qiuzhi99
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
12_login_logout
1 parent
8e9dd7c8
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
284 additions
and
10 deletions
client/src/App.css
client/src/App.js
client/src/context/auth.js
client/src/pages/Login.js
client/src/pages/Register.js
client/src/utils/hook.js
client/src/App.css
View file @
723d420
...
@@ -4,3 +4,8 @@
...
@@ -4,3 +4,8 @@
font-size
:
2rem
;
font-size
:
2rem
;
margin-top
:
10px
;
margin-top
:
10px
;
}
}
.form-container
{
width
:
400px
;
margin
:
0
auto
;
}
client/src/App.js
View file @
723d420
...
@@ -10,8 +10,11 @@ import Register from "./pages/Register";
...
@@ -10,8 +10,11 @@ import Register from "./pages/Register";
import
MenuBar
from
"./components/MenuBar"
;
import
MenuBar
from
"./components/MenuBar"
;
import
"./App.css"
;
import
"./App.css"
;
import
{
AuthProvider
}
from
"./context/auth"
;
function
App
()
{
function
App
()
{
return
(
return
(
<
AuthProvider
>
<
Router
>
<
Router
>
<
Container
>
<
Container
>
<
MenuBar
/>
<
MenuBar
/>
...
@@ -20,6 +23,7 @@ function App() {
...
@@ -20,6 +23,7 @@ function App() {
<
Route
exact
path
=
"/register"
component
=
{
Register
}
/
>
<
Route
exact
path
=
"/register"
component
=
{
Register
}
/
>
<
/Container
>
<
/Container
>
<
/Router
>
<
/Router
>
<
/AuthProvider
>
);
);
}
}
...
...
client/src/context/auth.js
0 → 100644
View file @
723d420
import
React
,
{
createContext
,
useReducer
}
from
"react"
;
const
AuthContext
=
createContext
({
user
:
null
,
login
:
userData
=>
{},
logout
:
()
=>
{}
});
function
authReducer
(
state
,
action
)
{
switch
(
action
.
type
)
{
case
"LOGIN"
:
return
{
...
state
,
user
:
action
.
payload
};
case
"LOGOUT"
:
return
{
...
state
,
user
:
null
};
default
:
return
state
;
}
}
function
AuthProvider
(
props
)
{
const
[
state
,
dispatch
]
=
useReducer
(
authReducer
,
{
user
:
null
});
function
login
(
userData
)
{
dispatch
({
type
:
"LOGIN"
,
payload
:
userData
});
}
function
logout
()
{
dispatch
({
type
:
"LOGOUT"
});
}
return
(
<
AuthContext
.
Provider
value
=
{{
user
:
state
.
user
,
login
,
logout
}}
{...
props
}
/
>
);
}
export
{
AuthContext
,
AuthProvider
};
client/src/pages/Login.js
View file @
723d420
import
React
from
"react"
;
import
React
,
{
useState
,
useContext
}
from
"react"
;
import
{
Form
,
Button
}
from
"semantic-ui-react"
;
import
gql
from
"graphql-tag"
;
import
{
useMutation
}
from
"@apollo/react-hooks"
;
import
{
useForm
}
from
"../utils/hook"
;
import
{
AuthContext
}
from
"../context/auth"
;
const
Login
=
props
=>
{
const
context
=
useContext
(
AuthContext
);
const
[
errors
,
setErrors
]
=
useState
({});
const
{
onChange
,
onSubmit
,
values
}
=
useForm
(
loginUser
,
{
username
:
""
,
password
:
""
});
const
[
addUser
,
{
loading
}]
=
useMutation
(
LOGIN_USER
,
{
update
(
_
,
{
data
:
{
login
:
userData
}
}
)
{
context
.
login
(
userData
);
props
.
history
.
push
(
"/"
);
},
onError
(
err
)
{
setErrors
(
err
.
graphQLErrors
[
0
].
extensions
.
exception
.
errors
);
},
variables
:
values
});
function
loginUser
()
{
addUser
();
}
function
Login
()
{
return
(
return
(
<
div
>
<
div
className
=
"form-container"
>
<
h1
>
Login
page
<
/h1
>
<
Form
onSubmit
=
{
onSubmit
}
noValidate
className
=
{
loading
?
"loading"
:
""
}
>
<
h1
>
Login
<
/h1
>
<
Form
.
Input
label
=
"Username"
placeholder
=
"Username..."
name
=
"username"
type
=
"text"
error
=
{
errors
.
username
?
true
:
false
}
value
=
{
values
.
username
}
onChange
=
{
onChange
}
><
/Form.Input
>
<
Form
.
Input
label
=
"Password"
placeholder
=
"Password..."
name
=
"password"
type
=
"password"
error
=
{
errors
.
password
?
true
:
false
}
value
=
{
values
.
password
}
onChange
=
{
onChange
}
><
/Form.Input
>
<
Button
type
=
"submit"
primary
>
Login
<
/Button
>
<
/Form
>
{
Object
.
keys
(
errors
).
length
>
0
&&
(
<
div
className
=
"ui error message"
>
<
ul
className
=
"list"
>
{
Object
.
values
(
errors
).
map
(
value
=>
(
<
li
key
=
{
value
}
>
{
value
}
<
/li
>
))}
<
/ul
>
<
/div
>
)}
<
/div
>
<
/div
>
);
);
}
};
const
LOGIN_USER
=
gql
`
mutation login($username: String!, $password: String!) {
login(username: $username, password: $password) {
id
email
username
createdAt
token
}
}
`
;
export
default
Login
;
export
default
Login
;
client/src/pages/Register.js
View file @
723d420
import
React
from
"react"
;
import
React
,
{
useState
,
useContext
}
from
"react"
;
import
{
Form
,
Button
}
from
"semantic-ui-react"
;
import
gql
from
"graphql-tag"
;
import
{
useMutation
}
from
"@apollo/react-hooks"
;
import
{
useForm
}
from
"../utils/hook"
;
import
{
AuthContext
}
from
"../context/auth"
;
const
Register
=
props
=>
{
const
context
=
useContext
(
AuthContext
);
const
[
errors
,
setErrors
]
=
useState
({});
const
{
onChange
,
onSubmit
,
values
}
=
useForm
(
registerUser
,
{
username
:
""
,
email
:
""
,
password
:
""
,
confirmPassword
:
""
});
const
[
addUser
,
{
loading
}]
=
useMutation
(
REGISTER_USER
,
{
update
(
_
,
{
data
:
{
register
:
userData
}
}
)
{
context
.
login
(
userData
);
props
.
history
.
push
(
"/"
);
},
onError
(
err
)
{
setErrors
(
err
.
graphQLErrors
[
0
].
extensions
.
exception
.
errors
);
},
variables
:
values
});
function
registerUser
()
{
addUser
();
}
function
Register
()
{
return
(
return
(
<
div
>
<
div
className
=
"form-container"
>
<
h1
>
Register
page
<
/h1
>
<
Form
onSubmit
=
{
onSubmit
}
noValidate
className
=
{
loading
?
"loading"
:
""
}
>
<
h1
>
Register
<
/h1
>
<
Form
.
Input
label
=
"Username"
placeholder
=
"Username..."
name
=
"username"
type
=
"text"
error
=
{
errors
.
username
?
true
:
false
}
value
=
{
values
.
username
}
onChange
=
{
onChange
}
><
/Form.Input
>
<
Form
.
Input
label
=
"Email"
placeholder
=
"Email..."
name
=
"email"
type
=
"email"
error
=
{
errors
.
email
?
true
:
false
}
value
=
{
values
.
email
}
onChange
=
{
onChange
}
><
/Form.Input
>
<
Form
.
Input
label
=
"Password"
placeholder
=
"Password..."
name
=
"password"
type
=
"password"
error
=
{
errors
.
password
?
true
:
false
}
value
=
{
values
.
password
}
onChange
=
{
onChange
}
><
/Form.Input
>
<
Form
.
Input
label
=
"Confirm Password"
placeholder
=
"Password..."
name
=
"confirmPassword"
type
=
"password"
error
=
{
errors
.
confirmPassword
?
true
:
false
}
value
=
{
values
.
confirmPassword
}
onChange
=
{
onChange
}
><
/Form.Input
>
<
Button
type
=
"submit"
primary
>
Register
<
/Button
>
<
/Form
>
{
Object
.
keys
(
errors
).
length
>
0
&&
(
<
div
className
=
"ui error message"
>
<
ul
className
=
"list"
>
{
Object
.
values
(
errors
).
map
(
value
=>
(
<
li
key
=
{
value
}
>
{
value
}
<
/li
>
))}
<
/ul
>
<
/div
>
)}
<
/div
>
<
/div
>
);
);
}
};
const
REGISTER_USER
=
gql
`
mutation register(
$username: String!
$email: String!
$password: String!
$confirmPassword: String!
) {
register(
registerInput: {
username: $username
email: $email
password: $password
confirmPassword: $confirmPassword
}
) {
id
email
username
createdAt
token
}
}
`
;
export
default
Register
;
export
default
Register
;
client/src/utils/hook.js
0 → 100644
View file @
723d420
import
{
useState
}
from
"react"
;
export
const
useForm
=
(
callback
,
initialState
=
{})
=>
{
const
[
values
,
setValues
]
=
useState
(
initialState
);
const
onChange
=
event
=>
{
setValues
({
...
values
,
[
event
.
target
.
name
]:
event
.
target
.
value
});
};
const
onSubmit
=
event
=>
{
event
.
preventDefault
();
callback
();
};
return
{
onChange
,
onSubmit
,
values
};
};
Write
Preview
Markdown
is supported
Attach a file
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 post a comment