Login start
This commit is contained in:
@@ -4,12 +4,34 @@
|
||||
import React, { Component } from 'react';
|
||||
import LinkList from './LinkList';
|
||||
import CreateLink from './CreateLink'
|
||||
import Header from './Header';
|
||||
import Login from './Login'
|
||||
import { Switch, Route } from 'react-router-dom';
|
||||
|
||||
class App extends Component {
|
||||
render() {
|
||||
return <CreateLink />;
|
||||
}
|
||||
}
|
||||
const App = () => {
|
||||
return (
|
||||
<div className="center w85">
|
||||
<Header />
|
||||
<div className="ph3 pv1 background-gray">
|
||||
<Switch>
|
||||
<Route exact path="/" component={LinkList} />
|
||||
<Route
|
||||
exact
|
||||
path="/create"
|
||||
component={CreateLink}
|
||||
/>
|
||||
<Route exact path="/login" component={Login} />
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// class App extends Component {
|
||||
// render() {
|
||||
// return <CreateLink />;
|
||||
// }
|
||||
// }
|
||||
|
||||
// function App() {
|
||||
// return (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { useHistory } from 'react-router';
|
||||
import { useMutation, gql } from '@apollo/client';
|
||||
|
||||
const CREATE_LINK_MUTATION = gql`
|
||||
@@ -17,6 +17,8 @@ const CREATE_LINK_MUTATION = gql`
|
||||
`;
|
||||
|
||||
const CreateLink = () => {
|
||||
const history = useHistory();
|
||||
|
||||
const [formState, setFormState] = useState({
|
||||
description: '',
|
||||
url: ''
|
||||
|
||||
90
client/src/components/Header.js
Normal file
90
client/src/components/Header.js
Normal file
@@ -0,0 +1,90 @@
|
||||
import React from 'react';
|
||||
import { useHistory } from 'react-router';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { AUTH_TOKEN } from '../constants';
|
||||
|
||||
const Header = () => {
|
||||
const history = useHistory();
|
||||
const authToken = localStorage.getItem(AUTH_TOKEN);
|
||||
return (
|
||||
<div className="flex pa1 justify-between nowrap orange">
|
||||
<div className="flex flex-fixed black">
|
||||
<div className="fw7 mr1">Hacker News</div>
|
||||
<Link to="/" className="ml1 no-underline black">
|
||||
new
|
||||
</Link>
|
||||
<div className="ml1">|</div>
|
||||
<Link to="/top" className="ml1 no-underline black">
|
||||
top
|
||||
</Link>
|
||||
<div className="ml1">|</div>
|
||||
<Link
|
||||
to="/search"
|
||||
className="ml1 no-underline black"
|
||||
>
|
||||
search
|
||||
</Link>
|
||||
{authToken && (
|
||||
<div className="flex">
|
||||
<div className="ml1">|</div>
|
||||
<Link
|
||||
to="/create"
|
||||
className="ml1 no-underline black"
|
||||
>
|
||||
submit
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-fixed">
|
||||
{authToken ? (
|
||||
<div
|
||||
className="ml1 pointer black"
|
||||
onClick={() => {
|
||||
localStorage.removeItem(AUTH_TOKEN);
|
||||
history.push(`/`);
|
||||
}}
|
||||
>
|
||||
logout
|
||||
</div>
|
||||
) : (
|
||||
<Link
|
||||
to="/login"
|
||||
className="ml1 no-underline black"
|
||||
>
|
||||
login
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
|
||||
// import React from 'react';
|
||||
// import { useHistory } from 'react-router';
|
||||
// import { Link, withRouter } from 'react-router-dom';
|
||||
|
||||
// const Header = () => {
|
||||
// const history = useHistory();
|
||||
// return (
|
||||
// <div className="flex pa1 justify-between nowrap orange">
|
||||
// <div className="flex flex-fixed black">
|
||||
// <div className="fw7 mr1">Hacker News</div>
|
||||
// <Link to="/" className="ml1 no-underline black">
|
||||
// new
|
||||
// </Link>
|
||||
// <div className="ml1">|</div>
|
||||
// <Link
|
||||
// to="/create"
|
||||
// className="ml1 no-underline black"
|
||||
// >
|
||||
// submit
|
||||
// </Link>
|
||||
// </div>
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
|
||||
// export default Header;
|
||||
133
client/src/components/Login.js
Normal file
133
client/src/components/Login.js
Normal file
@@ -0,0 +1,133 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useHistory } from 'react-router';
|
||||
import { useMutation, gql } from '@apollo/client';
|
||||
import { AUTH_TOKEN } from '../constants';
|
||||
|
||||
const SIGNUP_MUTATION = gql`
|
||||
mutation SignupMutation(
|
||||
$email: String!
|
||||
$password: String!
|
||||
$name: String!
|
||||
) {
|
||||
signup(
|
||||
email: $email
|
||||
password: $password
|
||||
name: $name
|
||||
) {
|
||||
token
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const LOGIN_MUTATION = gql`
|
||||
mutation LoginMutation(
|
||||
$email: String!
|
||||
$password: String!
|
||||
) {
|
||||
login(email: $email, password: $password) {
|
||||
token
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const Login = () => {
|
||||
const history = useHistory();
|
||||
|
||||
const [formState, setFormState] = useState({
|
||||
login: true,
|
||||
email: '',
|
||||
password: '',
|
||||
name: ''
|
||||
});
|
||||
|
||||
const [login] = useMutation(LOGIN_MUTATION, {
|
||||
variables: {
|
||||
email: formState.email,
|
||||
password: formState.password
|
||||
},
|
||||
onCompleted: ({ login }) => {
|
||||
localStorage.setItem(AUTH_TOKEN, login.token);
|
||||
history.push('/');
|
||||
}
|
||||
});
|
||||
|
||||
const [signup] = useMutation(SIGNUP_MUTATION, {
|
||||
variables: {
|
||||
name: formState.name,
|
||||
email: formState.email,
|
||||
password: formState.password
|
||||
},
|
||||
onCompleted: ({ signup }) => {
|
||||
localStorage.setItem(AUTH_TOKEN, signup.token);
|
||||
history.push('/');
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h4 className="mv3">
|
||||
{formState.login ? 'Login' : 'Sign Up'}
|
||||
</h4>
|
||||
<div className="flex flex-column">
|
||||
{!formState.login && (
|
||||
<input
|
||||
value={formState.name}
|
||||
onChange={(e) =>
|
||||
setFormState({
|
||||
...formState,
|
||||
name: e.target.value
|
||||
})
|
||||
}
|
||||
type="text"
|
||||
placeholder="Your name"
|
||||
/>
|
||||
)}
|
||||
<input
|
||||
value={formState.email}
|
||||
onChange={(e) =>
|
||||
setFormState({
|
||||
...formState,
|
||||
email: e.target.value
|
||||
})
|
||||
}
|
||||
type="text"
|
||||
placeholder="Your email address"
|
||||
/>
|
||||
<input
|
||||
value={formState.password}
|
||||
onChange={(e) =>
|
||||
setFormState({
|
||||
...formState,
|
||||
password: e.target.value
|
||||
})
|
||||
}
|
||||
type="password"
|
||||
placeholder="Choose a safe password"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex mt3">
|
||||
<button
|
||||
className="pointer mr2 button"
|
||||
onClick={formState.login ? login : signup}
|
||||
>
|
||||
{formState.login ? 'login' : 'create account'}
|
||||
</button>
|
||||
<button
|
||||
className="pointer button"
|
||||
onClick={(e) =>
|
||||
setFormState({
|
||||
...formState,
|
||||
login: !formState.login
|
||||
})
|
||||
}
|
||||
>
|
||||
{formState.login
|
||||
? 'need to create an account?'
|
||||
: 'already have an account?'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Login;
|
||||
Reference in New Issue
Block a user