This commit is contained in:
Jake McDermott
2018-09-26 20:56:58 -04:00
parent 0986ebef33
commit f8a4b01da5
6 changed files with 1429 additions and 71 deletions

49
.eslintrc Normal file
View File

@@ -0,0 +1,49 @@
{
"parser": "babel-eslint",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true,
"modules": true
}
},
"extends": [
"airbnb",
],
"settings": {
"react": {
"version": "16.5.2"
}
},
"env": {
"browser": true,
"node": true
},
"globals": {
"window": true,
},
"rules": {
"arrow-parens": "off",
"comma-dangle": "off",
"indent": ["error", 2, {
"SwitchCase": 1
}],
"max-len": ['error', {
"code": 100,
"ignoreStrings": true,
"ignoreTemplateLiterals": true,
}],
"no-continue": "off",
"no-debugger": "off",
"no-mixed-operators": "off",
"no-param-reassign": "off",
"no-plusplus": "off",
"no-underscore-dangle": "off",
"no-use-before-define": "off",
"no-multiple-empty-lines": ["error", { max: 1 }],
"object-curly-newline": "off",
"space-before-function-paren": ["error", "always"],
"no-trailing-spaces": ["error"],
}
}

1306
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,16 +5,23 @@
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"start": "webpack-dev-server --config ./webpack.config.js --mode development", "start": "webpack-dev-server --config ./webpack.config.js --mode development",
"test": "echo \"No test specified\" && exit 0" "test": "echo \"No test specified\" && exit 0",
"lint": "./node_modules/eslint/bin/eslint.js src/**/*.js src/**/*.jsx"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",
"license": "Apache", "license": "Apache",
"devDependencies": { "devDependencies": {
"babel-core": "^6.26.3", "babel-core": "^6.26.3",
"babel-eslint": "^10.0.0",
"babel-loader": "^7.1.5", "babel-loader": "^7.1.5",
"babel-preset-react": "^6.24.1", "babel-preset-react": "^6.24.1",
"babel-preset-stage-2": "^6.24.1", "babel-preset-stage-2": "^6.24.1",
"eslint": "^5.6.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-jsx-a11y": "^6.1.1",
"eslint-plugin-react": "^7.11.1",
"react-hot-loader": "^4.3.3", "react-hot-loader": "^4.3.3",
"webpack": "^4.15.1", "webpack": "^4.15.1",
"webpack-cli": "^3.0.8", "webpack-cli": "^3.0.8",

View File

@@ -10,18 +10,20 @@ const API_ORGANIZATIONS = `${API_V2}organizations/`;
const CSRF_COOKIE_NAME = 'csrftoken'; const CSRF_COOKIE_NAME = 'csrftoken';
const CSRF_HEADER_NAME = 'X-CSRFToken'; const CSRF_HEADER_NAME = 'X-CSRFToken';
const http = axios.create({
xsrfCookieName: CSRF_COOKIE_NAME,
xsrfHeaderName: CSRF_HEADER_NAME,
});
let authenticated = false; // temporary
class APIClient { class APIClient {
isAuthenticated() { constructor () {
return authenticated; this.authenticated = false; // temporary
this.http = axios.create({
xsrfCookieName: CSRF_COOKIE_NAME,
xsrfHeaderName: CSRF_HEADER_NAME,
});
} }
login(username, password, redirect = API_CONFIG) {
isAuthenticated () {
return this.authenticated;
}
login (username, password, redirect = API_CONFIG) {
const un = encodeURIComponent(username); const un = encodeURIComponent(username);
const pw = encodeURIComponent(password); const pw = encodeURIComponent(password);
const next = encodeURIComponent(redirect); const next = encodeURIComponent(redirect);
@@ -29,26 +31,26 @@ class APIClient {
const data = `username=${un}&password=${pw}&next=${next}`; const data = `username=${un}&password=${pw}&next=${next}`;
const headers = { 'Content-Type': 'application/x-www-form-urlencoded' }; const headers = { 'Content-Type': 'application/x-www-form-urlencoded' };
return http.get(API_LOGIN, { headers }) return this.http.get(API_LOGIN, { headers })
.then(() => http.post(API_LOGIN, data, { headers })) .then(() => this.http.post(API_LOGIN, data, { headers }))
.then(res => { .then(res => {
authenticated = true; // temporary this.authenticated = true; // temporary
return res; return res;
}) });
} }
logout() { logout () {
return http.delete(API_LOGIN); return this.http.delete(API_LOGIN);
} }
getProjects() { getProjects () {
return http.get(API_PROJECTS); return this.http.get(API_PROJECTS);
} }
getOrganizations() { getOrganizations () {
return http.get(API_ORGANIZATIONS); return this.http.get(API_ORGANIZATIONS);
} }
}; }
export default new APIClient(); export default new APIClient();

View File

@@ -7,67 +7,59 @@ import api from '../api';
class Login extends Component { class Login extends Component {
state = { state = {
username: '', username: '',
password: '', password: '',
redirect: false, redirect: false,
}; };
handleChange = event => this.setState({ [event.target.name]: event.target.value }); handleChange = event => this.setState({ [event.target.name]: event.target.value });
handleSubmit = event => { handleSubmit = event => {
const { username, password } = this.state; const { username, password } = this.state;
event.preventDefault(); event.preventDefault();
api.login(username, password) api.login(username, password)
.then(() => this.setState({ redirect: true })) .then(() => this.setState({ redirect: true }));
.then(() => api.getProjects()) }
.then(res => console.log(res));
};
render() { render () {
const { username, password, redirect } = this.state; const { username, password, redirect } = this.state;
if (redirect) { if (redirect) {
return (<Redirect to={'/'} />); return (<Redirect to="/" />);
} }
return ( return (
<div className='column'> <form onSubmit={this.handleSubmit}>
<form onSubmit={this.handleSubmit}> <div className="field">
<div className='field'> <label htmlFor="username">
<label className='label'>Username</label> Username
<div className='control'> <input
<input id="username"
className='input' name="username"
type='text' type="text"
name='username' onChange={this.handleChange}
onChange={this.handleChange} value={username}
value={username} />
required </label>
/> </div>
</div> <div>
</div> <label htmlFor="password">
<div className='field'> Password
<label className='label'>Password</label> <input
<div className='control'> id="password"
<input name="password"
className='input' type="password"
type='password' onChange={this.handleChange}
name='password' value={password}
onChange={this.handleChange} />
value={password} </label>
required </div>
/> <Button type="submit">
</div> Login
</div> </Button>
<div className='control'> </form>
<Button type='submit'>
Login
</Button>
</div>
</form>
</div>
); );
} }
} }

View File

@@ -1 +1,3 @@
import App from './App'; import App from './App';
export default App;