summaryrefslogtreecommitdiff
path: root/animism-align/frontend
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2021-03-05 19:10:55 +0100
committerJules Laplace <julescarbon@gmail.com>2021-03-05 19:10:55 +0100
commit0907418ce2c6ca498b02e8e514e4945d79750467 (patch)
treecdccf1157d01f5ead91a454d70e1f1769d945320 /animism-align/frontend
parentd5b6a4ea27f8c905e613363aab365066ad6d9cda (diff)
adding login view
Diffstat (limited to 'animism-align/frontend')
-rw-r--r--animism-align/frontend/app/actions.js2
-rw-r--r--animism-align/frontend/app/common/form.component.js3
-rw-r--r--animism-align/frontend/app/router.js30
-rw-r--r--animism-align/frontend/app/types.js1
-rw-r--r--animism-align/frontend/app/views/auth/auth.actions.js33
-rw-r--r--animism-align/frontend/app/views/auth/auth.css25
-rw-r--r--animism-align/frontend/app/views/auth/auth.gate.js29
-rw-r--r--animism-align/frontend/app/views/auth/auth.login.js76
8 files changed, 182 insertions, 17 deletions
diff --git a/animism-align/frontend/app/actions.js b/animism-align/frontend/app/actions.js
index c9a00f3..199661d 100644
--- a/animism-align/frontend/app/actions.js
+++ b/animism-align/frontend/app/actions.js
@@ -6,6 +6,7 @@ import * as transcriptActions from 'app/views/paragraph/transcript.actions'
import * as audioActions from 'app/views/audio/audio.actions'
import * as alignActions from 'app/views/align/align.actions'
import * as siteActions from 'app/views/site/site.actions'
+import * as authActions from 'app/views/auth/auth.actions'
import { store } from 'app/store'
@@ -23,6 +24,7 @@ export default
.map(a => [a, crudActions[a]])
.concat([
['site', siteActions],
+ ['auth', authActions],
['align', alignActions],
['audio', audioActions],
['viewer', viewerActions],
diff --git a/animism-align/frontend/app/common/form.component.js b/animism-align/frontend/app/common/form.component.js
index 4b6616e..37ef9e0 100644
--- a/animism-align/frontend/app/common/form.component.js
+++ b/animism-align/frontend/app/common/form.component.js
@@ -5,7 +5,7 @@ export const TextInput = props => (
<label className={(props.error ? 'error' : 'text') + (props.className ? ' ' + props.className : '')}>
{props.title && <span>{props.title}</span>}
<input
- type="text"
+ type={props.type || "text"}
required={props.required}
onChange={props.onChange}
onBlur={props.onBlur}
@@ -238,5 +238,6 @@ export const SubmitButton = (props) => (
className={props.className ? "submit " + props.className : "submit"}
onClick={props.onClick}
>{props.title}</button>
+ {props.after && <span>{props.after}</span>}
</label>
)
diff --git a/animism-align/frontend/app/router.js b/animism-align/frontend/app/router.js
index 982429b..e4ea05e 100644
--- a/animism-align/frontend/app/router.js
+++ b/animism-align/frontend/app/router.js
@@ -2,8 +2,7 @@ import React, { Component } from 'react'
import { ConnectedRouter } from 'connected-react-router'
import { Route } from 'react-router'
-import actions from 'app/actions'
-
+import AuthGate from 'app/views/auth/auth.gate'
import Header from 'app/views/nav/header.component'
import * as views from 'app/views'
@@ -17,22 +16,21 @@ const viewList = Object.keys(views).map(name => {
})
export default class Router extends Component {
- componentDidMount() {
- actions.site.loadProject()
- }
render() {
return (
- <ConnectedRouter history={this.props.history}>
- <div className='app'>
- <Header />
- {viewList}
- <Route exact key='root' path='/' render={() => {
- // redirect to index!!
- setTimeout(() => this.props.history.push('/align'), 10)
- return null
- }} />
- </div>
- </ConnectedRouter>
+ <AuthGate>
+ <ConnectedRouter history={this.props.history}>
+ <div className='app'>
+ <Header />
+ {viewList}
+ <Route exact key='root' path='/' render={() => {
+ // redirect to index!!
+ setTimeout(() => this.props.history.push('/align'), 10)
+ return null
+ }} />
+ </div>
+ </ConnectedRouter>
+ </AuthGate>
)
}
}
diff --git a/animism-align/frontend/app/types.js b/animism-align/frontend/app/types.js
index e1015d2..943527c 100644
--- a/animism-align/frontend/app/types.js
+++ b/animism-align/frontend/app/types.js
@@ -1,6 +1,7 @@
import { with_type, crud_type } from 'app/api/crud.types'
export const api = crud_type('api', [])
+export const auth = crud_type('auth', [])
export const upload = crud_type('upload', [])
export const media = crud_type('media', [])
diff --git a/animism-align/frontend/app/views/auth/auth.actions.js b/animism-align/frontend/app/views/auth/auth.actions.js
new file mode 100644
index 0000000..d7663b7
--- /dev/null
+++ b/animism-align/frontend/app/views/auth/auth.actions.js
@@ -0,0 +1,33 @@
+import fetch from 'node-fetch'
+
+import { session } from 'app/session'
+
+const urls = {
+ login: "/api/v1/auth/login",
+}
+
+export const login = (data) => dispatch => (
+ fetch(urls.login, {
+ method: 'POST',
+ body: JSON.stringify(data),
+ credentials: 'same-origin',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ }
+ })
+ .then(req => req.json())
+ .then(res => {
+ if (res.access_token) {
+ session.set('access_token', res.access_token)
+ }
+ return res
+ })
+ .catch(error => {
+ console.error(error)
+ })
+)
+
+export const logout = () => dispatch => {
+ session.set('access_token', '')
+}
diff --git a/animism-align/frontend/app/views/auth/auth.css b/animism-align/frontend/app/views/auth/auth.css
new file mode 100644
index 0000000..e9ceb85
--- /dev/null
+++ b/animism-align/frontend/app/views/auth/auth.css
@@ -0,0 +1,25 @@
+.auth {
+ position: fixed;
+ top: 0; left: 0;
+ width: 100%; height: 100%;
+ background: linear-gradient(#190051, #1c0406);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+.login {
+ background: #333;
+ padding: 1rem;
+ box-shadow: 0 5px 10px #000;
+}
+.login h6 {
+ width: 100%;
+ text-align: center;
+ font-family: 'Georgia', serif;
+ font-size: 1.5rem;
+ font-weight: normal;
+ font-style: italic;
+ margin: 0 0 1rem 0;
+ transform: skew(11deg);
+ color: #fff;
+}
diff --git a/animism-align/frontend/app/views/auth/auth.gate.js b/animism-align/frontend/app/views/auth/auth.gate.js
new file mode 100644
index 0000000..498d32a
--- /dev/null
+++ b/animism-align/frontend/app/views/auth/auth.gate.js
@@ -0,0 +1,29 @@
+import React, { Component } from 'react'
+
+import './auth.css'
+
+import actions from 'app/actions'
+
+import AuthLogin from './auth.login'
+
+export default class AuthGate extends Component {
+ constructor(props) {
+ super(props)
+ }
+
+ componentDidMount() {
+ // actions.site.loadProject()
+ }
+
+ componentDidUpdate() {
+
+ }
+
+ render() {
+ return (
+ <div className='auth'>
+ <AuthLogin />
+ </div>
+ )
+ }
+} \ No newline at end of file
diff --git a/animism-align/frontend/app/views/auth/auth.login.js b/animism-align/frontend/app/views/auth/auth.login.js
new file mode 100644
index 0000000..9ba4c0b
--- /dev/null
+++ b/animism-align/frontend/app/views/auth/auth.login.js
@@ -0,0 +1,76 @@
+import React, { Component } from 'react'
+
+import './auth.css'
+
+import actions from 'app/actions'
+import { TextInput, SubmitButton } from 'app/common'
+
+export default class AuthLogin extends Component {
+ state = {
+ data: {
+ username: "",
+ password: "",
+ },
+ error: null,
+ }
+
+ constructor(props) {
+ super(props)
+ this.handleChange = this.handleChange.bind(this)
+ this.handleSubmit = this.handleSubmit.bind(this)
+ }
+
+ handleChange(e) {
+ e && e.preventDefault()
+ console.log(e.target.name, e.target.value)
+ this.setState({
+ data: {
+ ...this.state.data,
+ [e.target.name]: e.target.value
+ }
+ })
+ }
+
+ handleSubmit(e) {
+ e && e.preventDefault()
+ this.setState({ error: null })
+ actions.auth.login(this.state)
+ .then(res => {
+ console.log(res)
+ if (res.error) {
+ this.props.onAuthenticate()
+ } else {
+ this.setState({ error })
+ }
+ })
+ }
+
+ render() {
+ return (
+ <form className='login' onSubmit={this.handleSubmit}>
+ <h6>
+ Welcome to the Animism Editor
+ </h6>
+ <TextInput
+ title="Username"
+ name="username"
+ data={this.state.data}
+ onChange={this.handleChange}
+ autoComplete="off"
+ />
+ <TextInput
+ type="password"
+ title="Password"
+ name="password"
+ data={this.state.data}
+ onChange={this.handleChange}
+ autoComplete="off"
+ />
+ <SubmitButton
+ title="Log in"
+ after={this.state.error}
+ />
+ </form>
+ )
+ }
+} \ No newline at end of file