798ae043ac
Fixes #153 This is my attempt at https://github.com/zeit/next.js/issues/153 Following @rauchg instructions: - it uses an authentication helper across pages which returns a token if there's one - it has session synchronization across tabs - <strike>I deployed a passwordless backend on `now.sh` (https://with-cookie-api.now.sh, [src](https://github.com/j0lv3r4/next.js-with-cookies-api))</strike> The backend is included in the repository and you can deploy everything together by running `now` Also, from reviewing other PRs, I made sure to: - use [isomorphic-unfetch](https://www.npmjs.com/package/isomorphic-unfetch). - use [next-cookies](https://www.npmjs.com/package/next-cookies). Here's a little demo: ![GIF](https://i.imgur.com/067Ph56.gif)
97 lines
2.2 KiB
JavaScript
97 lines
2.2 KiB
JavaScript
import { Component } from 'react'
|
|
import Layout from '../components/layout'
|
|
import { login } from '../utils/auth'
|
|
|
|
class Login extends Component {
|
|
static getInitialProps ({ req }) {
|
|
const apiUrl = process.browser
|
|
? `https://${window.location.host}/api/login.js`
|
|
: `https://${req.headers.host}/api/login.js`
|
|
|
|
return { apiUrl }
|
|
}
|
|
|
|
constructor (props) {
|
|
super(props)
|
|
|
|
this.state = { username: '', error: '' }
|
|
this.handleChange = this.handleChange.bind(this)
|
|
this.handleSubmit = this.handleSubmit.bind(this)
|
|
}
|
|
|
|
handleChange (event) {
|
|
this.setState({ username: event.target.value })
|
|
}
|
|
|
|
async handleSubmit (event) {
|
|
event.preventDefault()
|
|
const username = this.state.username
|
|
const url = this.props.apiUrl
|
|
login({ username, url }).catch(() =>
|
|
this.setState({ error: 'Login failed.' })
|
|
)
|
|
}
|
|
|
|
render () {
|
|
return (
|
|
<Layout>
|
|
<div className='login'>
|
|
<form onSubmit={this.handleSubmit}>
|
|
<label htmlFor='username'>GitHub username</label>
|
|
|
|
<input
|
|
type='text'
|
|
id='username'
|
|
name='username'
|
|
value={this.state.username}
|
|
onChange={this.handleChange}
|
|
/>
|
|
|
|
<button type='submit'>Login</button>
|
|
|
|
<p className={`error ${this.state.error && 'show'}`}>
|
|
{this.state.error && `Error: ${this.state.error}`}
|
|
</p>
|
|
</form>
|
|
</div>
|
|
<style jsx>{`
|
|
.login {
|
|
max-width: 340px;
|
|
margin: 0 auto;
|
|
padding: 1rem;
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
form {
|
|
display: flex;
|
|
flex-flow: column;
|
|
}
|
|
|
|
label {
|
|
font-weight: 600;
|
|
}
|
|
|
|
input {
|
|
padding: 8px;
|
|
margin: 0.3rem 0 1rem;
|
|
border: 1px solid #ccc;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.error {
|
|
margin: 0.5rem 0 0;
|
|
display: none;
|
|
color: brown;
|
|
}
|
|
|
|
.error.show {
|
|
display: block;
|
|
}
|
|
`}</style>
|
|
</Layout>
|
|
)
|
|
}
|
|
}
|
|
|
|
export default Login
|