Commit 723d4202 by qiuzhi99

12_login_logout

1 parent 8e9dd7c8
......@@ -4,3 +4,8 @@
font-size: 2rem;
margin-top: 10px;
}
.form-container {
width: 400px;
margin: 0 auto;
}
......@@ -10,16 +10,20 @@ import Register from "./pages/Register";
import MenuBar from "./components/MenuBar";
import "./App.css";
import { AuthProvider } from "./context/auth";
function App() {
return (
<Router>
<Container>
<MenuBar />
<Route exact path="/" component={Home} />
<Route exact path="/login" component={Login} />
<Route exact path="/register" component={Register} />
</Container>
</Router>
<AuthProvider>
<Router>
<Container>
<MenuBar />
<Route exact path="/" component={Home} />
<Route exact path="/login" component={Login} />
<Route exact path="/register" component={Register} />
</Container>
</Router>
</AuthProvider>
);
}
......
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 };
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 (
<div>
<h1>Login page</h1>
<div className="form-container">
<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>
);
}
};
const LOGIN_USER = gql`
mutation login($username: String!, $password: String!) {
login(username: $username, password: $password) {
id
email
username
createdAt
token
}
}
`;
export default Login;
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 (
<div>
<h1>Register page</h1>
<div className="form-container">
<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>
);
}
};
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;
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
};
};
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!