mirror of
https://github.com/wassname/talk.git
synced 2026-07-08 19:45:29 +08:00
Merge branch 'master' into yarn-docker
This commit is contained in:
@@ -1,5 +1,29 @@
|
||||
import * as actions from '../constants/auth';
|
||||
import coralApi from '../../../coral-framework/helpers/response';
|
||||
import coralApi from 'coral-framework/helpers/response';
|
||||
|
||||
// Log In.
|
||||
export const handleLogin = (email, password) => dispatch => {
|
||||
dispatch({type: actions.LOGIN_REQUEST});
|
||||
return coralApi('/auth/local', {method: 'POST', body: {email, password}})
|
||||
.then(result => {
|
||||
const isAdmin = !!result.user.roles.filter(i => i === 'ADMIN').length;
|
||||
dispatch(checkLoginSuccess(result.user, isAdmin));
|
||||
})
|
||||
.catch(error => {
|
||||
dispatch({type: actions.LOGIN_FAILURE, message: error.translation_key});
|
||||
});
|
||||
};
|
||||
|
||||
const forgotPassowordRequest = () => ({type: actions.FETCH_FORGOT_PASSWORD_REQUEST});
|
||||
const forgotPassowordSuccess = () => ({type: actions.FETCH_FORGOT_PASSWORD_SUCCESS});
|
||||
const forgotPassowordFailure = () => ({type: actions.FETCH_FORGOT_PASSWORD_FAILURE});
|
||||
|
||||
export const requestPasswordReset = email => dispatch => {
|
||||
dispatch(forgotPassowordRequest(email));
|
||||
return coralApi('/account/password/reset', {method: 'POST', body: {email}})
|
||||
.then(() => dispatch(forgotPassowordSuccess()))
|
||||
.catch(error => dispatch(forgotPassowordFailure(error)));
|
||||
};
|
||||
|
||||
// Check Login
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
import React, {PropTypes} from 'react';
|
||||
import Layout from 'coral-admin/src/components/ui/Layout';
|
||||
import styles from './NotFound.css';
|
||||
import {Button, TextField, Alert, Success} from 'coral-ui';
|
||||
import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from '../translations';
|
||||
const lang = new I18n(translations);
|
||||
|
||||
class AdminLogin extends React.Component {
|
||||
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.state = {email: '', password: '', requestPassword: false};
|
||||
}
|
||||
|
||||
handleSignIn = e => {
|
||||
e.preventDefault();
|
||||
this.props.handleLogin(this.state.email, this.state.password);
|
||||
}
|
||||
|
||||
handleRequestPassword = e => {
|
||||
e.preventDefault();
|
||||
this.props.requestPasswordReset(this.state.email);
|
||||
}
|
||||
|
||||
render () {
|
||||
const {errorMessage} = this.props;
|
||||
const signInForm = (
|
||||
<form onSubmit={this.handleSignIn}>
|
||||
{errorMessage && <Alert>{lang.t(`errors.${errorMessage}`)}</Alert>}
|
||||
<TextField
|
||||
label='Email Address'
|
||||
value={this.state.email}
|
||||
onChange={e => this.setState({email: e.target.value})} />
|
||||
<TextField
|
||||
label='Password'
|
||||
value={this.state.password}
|
||||
onChange={e => this.setState({password: e.target.value})}
|
||||
type='password' />
|
||||
<div style={{height: 10}}></div>
|
||||
<Button
|
||||
type='submit'
|
||||
cStyle='black'
|
||||
full
|
||||
onClick={this.handleSignIn}>Sign In</Button>
|
||||
<p className={styles.forgotPasswordCTA}>
|
||||
Forgot your password? <a href="#" className={styles.forgotPasswordLink} onClick={e => {
|
||||
e.preventDefault();
|
||||
this.setState({requestPassword: true});
|
||||
}}>Request a new one.</a>
|
||||
</p>
|
||||
</form>
|
||||
);
|
||||
const requestPasswordForm = (
|
||||
this.props.passwordRequestSuccess
|
||||
? <p className={styles.passwordRequestSuccess} onClick={() => {
|
||||
location.href = location.href;
|
||||
}}>
|
||||
{this.props.passwordRequestSuccess} <a className={styles.signInLink} href="#">Sign in</a>
|
||||
<Success />
|
||||
</p>
|
||||
: <form onSubmit={this.handleRequestPassword}>
|
||||
<TextField
|
||||
label='Email Address'
|
||||
value={this.state.email}
|
||||
onChange={e => this.setState({email: e.target.value})} />
|
||||
<Button
|
||||
type='submit'
|
||||
cStyle='black'
|
||||
full
|
||||
onClick={this.handleRequestPassword}>Reset Password</Button>
|
||||
</form>
|
||||
);
|
||||
return (
|
||||
<Layout fixedDrawer restricted={true}>
|
||||
<div className={styles.loginLayout}>
|
||||
<h1 className={styles.loginHeader}>Team sign in</h1>
|
||||
<p className={styles.loginCTA}>Sign in to interact with your community.</p>
|
||||
{ this.state.requestPassword ? requestPasswordForm : signInForm }
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AdminLogin.propTypes = {
|
||||
handleLogin: PropTypes.func.isRequired,
|
||||
passwordRequestSuccess: PropTypes.string,
|
||||
loginError: PropTypes.string
|
||||
};
|
||||
|
||||
export default AdminLogin;
|
||||
@@ -1,12 +1,37 @@
|
||||
.layout {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.loginLayout {
|
||||
max-width: 400px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.loginHeader, .loginCTA, .forgotPasswordCTA, .passwordRequestSuccess {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.forgotPasswordLink, .signInLink {
|
||||
color: blue;
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.forgotPasswordLink:hover, .signInLink:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.layout h1 {
|
||||
font-size: 40px;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.layout img {
|
||||
width: 100%;
|
||||
.loginHeader {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.passwordRequestSuccess {
|
||||
cursor: pointer;
|
||||
padding: 8px 14px;
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
import React from 'react';
|
||||
import {Layout} from 'react-mdl';
|
||||
import styles from './NotFound.css';
|
||||
|
||||
export const PermissionRequired = () => (
|
||||
<Layout fixedDrawer>
|
||||
<div className={styles.layout} >
|
||||
<h1>Permission Required</h1>
|
||||
<p>We’re sorry, but you don’t have access to that page.</p>
|
||||
<img src="https://coralproject.net/images/communicorn.jpg" alt="Communicorn"/>
|
||||
</div>
|
||||
</Layout>
|
||||
);
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from 'react';
|
||||
import React, {PropTypes} from 'react';
|
||||
import {Navigation, Drawer} from 'react-mdl';
|
||||
import {IndexLink, Link} from 'react-router';
|
||||
import styles from './Drawer.css';
|
||||
import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from '../../translations.json';
|
||||
|
||||
export default ({handleLogout, restricted = false}) => (
|
||||
const CoralDrawer = ({handleLogout, restricted = false}) => (
|
||||
<Drawer className={styles.header}>
|
||||
{ !restricted ?
|
||||
<div>
|
||||
@@ -45,5 +45,11 @@ export default ({handleLogout, restricted = false}) => (
|
||||
</Drawer>
|
||||
);
|
||||
|
||||
CoralDrawer.propTypes = {
|
||||
handleLogout: PropTypes.func.isRequired,
|
||||
restricted: PropTypes.bool // hide app elements from a logged out user
|
||||
};
|
||||
|
||||
const lang = new I18n(translations);
|
||||
|
||||
export default CoralDrawer;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, {PropTypes} from 'react';
|
||||
import {Navigation, Header, IconButton, MenuItem, Menu} from 'react-mdl';
|
||||
import {Link, IndexLink} from 'react-router';
|
||||
import styles from './Header.css';
|
||||
@@ -6,7 +6,7 @@ import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from '../../translations.json';
|
||||
import {Logo} from './Logo';
|
||||
|
||||
export default ({handleLogout, restricted = false}) => (
|
||||
const CoralHeader = ({handleLogout, restricted = false}) => (
|
||||
<Header className={styles.header}>
|
||||
<Logo className={styles.logo} />
|
||||
{
|
||||
@@ -64,4 +64,11 @@ export default ({handleLogout, restricted = false}) => (
|
||||
</Header>
|
||||
);
|
||||
|
||||
CoralHeader.propTypes = {
|
||||
handleLogout: PropTypes.func.isRequired,
|
||||
restricted: PropTypes.bool // hide elemnts from a user that's logged out
|
||||
};
|
||||
|
||||
const lang = new I18n(translations);
|
||||
|
||||
export default CoralHeader;
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
import React from 'react';
|
||||
import React, {PropTypes} from 'react';
|
||||
import {Layout as LayoutMDL} from 'react-mdl';
|
||||
import Header from './Header';
|
||||
import Drawer from './Drawer';
|
||||
import styles from './Layout.css';
|
||||
|
||||
export const Layout = ({children, ...props}) => (
|
||||
const Layout = ({children, handleLogout = () => {}, restricted = false, ...props}) => (
|
||||
<LayoutMDL fixedDrawer>
|
||||
<Header {...props} />
|
||||
<Drawer {...props} />
|
||||
<div className={styles.layout} >
|
||||
<Header handleLogout={handleLogout} restricted={restricted} {...props} />
|
||||
<Drawer handleLogout={handleLogout} restricted={restricted} {...props} />
|
||||
<div className={styles.layout}>
|
||||
{children}
|
||||
</div>
|
||||
</LayoutMDL>
|
||||
);
|
||||
|
||||
Layout.propTypes = {
|
||||
handleLogout: PropTypes.func,
|
||||
restricted: PropTypes.bool // hide elements from a user that's logged out
|
||||
};
|
||||
|
||||
export default Layout;
|
||||
|
||||
@@ -7,3 +7,11 @@ export const CHECK_CSRF_TOKEN = 'CHECK_CSRF_TOKEN';
|
||||
export const LOGOUT_REQUEST = 'LOGOUT_REQUEST';
|
||||
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
|
||||
export const LOGOUT_FAILURE = 'LOGOUT_FAILURE';
|
||||
|
||||
export const LOGIN_REQUEST = 'LOGIN_REQUEST';
|
||||
export const LOGIN_SUCCESS = 'LOGIN_SUCCESS';
|
||||
export const LOGIN_FAILURE = 'LOGIN_FAILURE';
|
||||
|
||||
export const FETCH_FORGOT_PASSWORD_REQUEST = 'FETCH_FORGOT_PASSWORD_REQUEST';
|
||||
export const FETCH_FORGOT_PASSWORD_SUCCESS = 'FETCH_FORGOT_PASSWORD_SUCCESS';
|
||||
export const FETCH_FORGOT_PASSWORD_FAILURE = 'FETCH_FORGOT_PASSWORD_FAILURE';
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import styles from './style.css';
|
||||
import {Wizard, WizardNav} from 'coral-ui';
|
||||
import {Layout} from '../../components/ui/Layout';
|
||||
import Layout from 'coral-admin/src/components/ui/Layout';
|
||||
|
||||
import {
|
||||
goToStep,
|
||||
|
||||
@@ -1,24 +1,33 @@
|
||||
import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {Layout} from '../components/ui/Layout';
|
||||
import {checkLogin, logout} from '../actions/auth';
|
||||
import Layout from '../components/ui/Layout';
|
||||
import {checkLogin, handleLogin, logout, requestPasswordReset} from '../actions/auth';
|
||||
import {FullLoading} from '../components/FullLoading';
|
||||
import {PermissionRequired} from '../components/PermissionRequired';
|
||||
import AdminLogin from '../components/AdminLogin';
|
||||
|
||||
class LayoutContainer extends Component {
|
||||
componentWillMount () {
|
||||
const {checkLogin} = this.props;
|
||||
checkLogin().then(() => {
|
||||
if (!this.props.auth.isAdmin) {
|
||||
location.href = '/admin/login';
|
||||
}
|
||||
});
|
||||
checkLogin();
|
||||
}
|
||||
render () {
|
||||
const {isAdmin, loggedIn, loadingUser} = this.props.auth;
|
||||
const {
|
||||
isAdmin,
|
||||
loggedIn,
|
||||
loadingUser,
|
||||
loginError,
|
||||
passwordRequestSuccess
|
||||
} = this.props.auth;
|
||||
const {handleLogout} = this.props;
|
||||
if (loadingUser) { return <FullLoading />; }
|
||||
if (!isAdmin) { return <PermissionRequired />; }
|
||||
if (isAdmin && loggedIn) { return <Layout {...this.props} />; }
|
||||
if (!isAdmin) {
|
||||
return <AdminLogin
|
||||
handleLogin={this.props.handleLogin}
|
||||
requestPasswordReset={this.props.requestPasswordReset}
|
||||
passwordRequestSuccess={passwordRequestSuccess}
|
||||
errorMessage={loginError} />;
|
||||
}
|
||||
if (isAdmin && loggedIn) { return <Layout handleLogout={handleLogout} {...this.props} />; }
|
||||
return <FullLoading />;
|
||||
}
|
||||
}
|
||||
@@ -29,6 +38,8 @@ const mapStateToProps = state => ({
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
checkLogin: () => dispatch(checkLogin()),
|
||||
handleLogin: (username, password) => dispatch(handleLogin(username, password)),
|
||||
requestPasswordReset: email => dispatch(requestPasswordReset(email)),
|
||||
handleLogout: () => dispatch(logout())
|
||||
});
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@ import * as actions from '../constants/auth';
|
||||
const initialState = Map({
|
||||
loggedIn: false,
|
||||
user: null,
|
||||
isAdmin: false
|
||||
isAdmin: false,
|
||||
loginError: null,
|
||||
passwordRequestSuccess: null
|
||||
});
|
||||
|
||||
export default function auth (state = initialState, action) {
|
||||
@@ -25,6 +27,14 @@ export default function auth (state = initialState, action) {
|
||||
.set('user', action.user);
|
||||
case actions.LOGOUT_SUCCESS:
|
||||
return initialState;
|
||||
case actions.LOGIN_REQUEST:
|
||||
return state.set('loginError', null);
|
||||
case actions.LOGIN_FAILURE:
|
||||
return state.set('loginError', action.message);
|
||||
case actions.FETCH_FORGOT_PASSWORD_REQUEST:
|
||||
return state.set('passwordRequestSuccess', null);
|
||||
case actions.FETCH_FORGOT_PASSWORD_SUCCESS:
|
||||
return state.set('passwordRequestSuccess', 'If you have a registered account, a password reset link was sent to that email.');
|
||||
default :
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"en": {
|
||||
"errors": {
|
||||
"NOT_AUTHORIZED": "Your username or password is not recognized by our system."
|
||||
},
|
||||
"community": {
|
||||
"username_and_email": "Username and Email",
|
||||
"account_creation_date": "Account Creation Date",
|
||||
@@ -134,6 +137,9 @@
|
||||
}
|
||||
},
|
||||
"es": {
|
||||
"errors": {
|
||||
"NOT_AUTHORIZED": "Acción no autorizada."
|
||||
},
|
||||
"community": {
|
||||
"username_and_email": "Usuario y E-mail",
|
||||
"account_creation_date": "Fecha de creación de la cuenta",
|
||||
@@ -215,7 +221,7 @@
|
||||
},
|
||||
"bandialog": {
|
||||
"ban_user": "Quieres suspender el Usuario?",
|
||||
"are_you_sure": "Estas segura que quieres suspender a {props.author.username}?",
|
||||
"are_you_sure": "Estas segura que quieres suspender a {0}?",
|
||||
"note": "Nota: Suspender este usuario también va a colocar este comentario en la cola de Rechazados.",
|
||||
"cancel": "Cancelar",
|
||||
"yes_ban_user": "Si, Suspendan el usuario"
|
||||
|
||||
@@ -40,7 +40,7 @@ export const postComment = graphql(POST_COMMENT, {
|
||||
updateQueries: {
|
||||
AssetQuery: (oldData, {mutationResult:{data:{createComment:{comment}}}}) => {
|
||||
|
||||
if (oldData.asset.moderation === 'PRE') {
|
||||
if (oldData.asset.settings.moderation === 'PRE') {
|
||||
return oldData;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import React from 'react';
|
||||
import TextField from 'coral-ui/components/TextField';
|
||||
import Alert from './Alert';
|
||||
import Button from 'coral-ui/components/Button';
|
||||
import {Dialog} from 'coral-ui';
|
||||
import {Dialog, Alert} from 'coral-ui';
|
||||
import FakeComment from './FakeComment';
|
||||
|
||||
import styles from './styles.css';
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React, {PropTypes} from 'react';
|
||||
import Alert from './Alert';
|
||||
import {Button, TextField, Spinner, Success} from 'coral-ui';
|
||||
import {Button, TextField, Spinner, Success, Alert} from 'coral-ui';
|
||||
import styles from './styles.css';
|
||||
import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from '../translations';
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React, {PropTypes} from 'react';
|
||||
import Alert from './Alert';
|
||||
import {Button, TextField, Spinner, Success} from 'coral-ui';
|
||||
import {Button, TextField, Spinner, Success, Alert} from 'coral-ui';
|
||||
import styles from './styles.css';
|
||||
import I18n from 'coral-framework/modules/i18n/i18n';
|
||||
import translations from '../translations';
|
||||
|
||||
@@ -65,23 +65,6 @@ input.error{
|
||||
padding: 3px 0 16px;
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 10px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.alert--success {
|
||||
border: solid 1px #1ec00e;
|
||||
background: #cbf1b8;
|
||||
color: #006900;
|
||||
}
|
||||
|
||||
.alert--error {
|
||||
background: #FFEBEE;
|
||||
color: #B71C1C;
|
||||
}
|
||||
|
||||
.userBox {
|
||||
padding: 10px 0 20px;
|
||||
letter-spacing: 0.1px;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
.alert {
|
||||
padding: 10px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.alert--success {
|
||||
border: solid 1px #1ec00e;
|
||||
background: #cbf1b8;
|
||||
color: #006900;
|
||||
}
|
||||
|
||||
.alert--error {
|
||||
background: #FFEBEE;
|
||||
color: #B71C1C;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import styles from './styles.css';
|
||||
import styles from './Alert.css';
|
||||
|
||||
const Alert = ({cStyle = 'error', children, className, ...props}) => (
|
||||
<div
|
||||
@@ -1,3 +1,4 @@
|
||||
export {default as Alert} from './components/Alert';
|
||||
export {default as Dialog} from './components/Dialog';
|
||||
export {default as CoralLogo} from './components/CoralLogo';
|
||||
export {default as FabButton} from './components/FabButton';
|
||||
|
||||
@@ -15,10 +15,6 @@ router.get('/password-reset', (req, res) => {
|
||||
res.render('password-reset', {redirectUri: process.env.TALK_ROOT_URL});
|
||||
});
|
||||
|
||||
router.get('/login', (req, res, next) => {
|
||||
res.render('admin/login');
|
||||
});
|
||||
|
||||
router.get('*', (req, res) => {
|
||||
res.render('admin', {basePath: '/client/coral-admin'});
|
||||
});
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
|
||||
<title>Admin Login</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
||||
<link rel="stylesheet" href="https://code.getmdl.io/1.2.1/material.indigo-pink.min.css">
|
||||
|
||||
<style media="screen">
|
||||
body, #root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
#root form {
|
||||
max-width: 300px;
|
||||
border: 1px solid lightgrey;
|
||||
box-shadow: 0px 10px 24px 2px rgba(0,0,0,0.2);
|
||||
margin: 50px auto;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.legend {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 3px;
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
small {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
input {
|
||||
border-radius: 4px;
|
||||
margin-top: 3px;
|
||||
border: 1px solid lightgrey;
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
padding: 14px;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.submit-password-reset {
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
display: block;
|
||||
background-color: #333;
|
||||
color: white;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
margin-top: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.error-console {
|
||||
display: none;
|
||||
margin-top: 10px;
|
||||
border-radius: 4px;
|
||||
background-color: pink;
|
||||
color: red;
|
||||
border: 1px solid red;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.error-console.active {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
<form id="login-form">
|
||||
<legend class="legend">Admin Login</legend>
|
||||
<label for="email">
|
||||
Email
|
||||
<input type="email" name="email" placeholder=""/>
|
||||
</label>
|
||||
|
||||
<label for="password">
|
||||
Password
|
||||
<input type="password" name="password" placeholder="" />
|
||||
</label>
|
||||
<button class="submit-password-reset" type="submit">Login</button>
|
||||
<div class="error-console"></div>
|
||||
</form>
|
||||
</div>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
function showError(message) {
|
||||
$('.error-console').text(message).addClass('active');
|
||||
}
|
||||
|
||||
function handleSubmit (e) {
|
||||
e.preventDefault();
|
||||
$('.error-console').removeClass('active');
|
||||
|
||||
var password = $('[name="password"]').val();
|
||||
var email = $('[name="email"]').val();
|
||||
|
||||
$.ajax({
|
||||
url: '/api/v1/auth/local',
|
||||
contentType: 'application/json',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRF-Token': '<%= csrfToken %>'
|
||||
},
|
||||
data: JSON.stringify({password: password, email: email})
|
||||
}).then(function (success) {
|
||||
location.href = '/admin';
|
||||
}).catch(function (error) {
|
||||
showError(error.responseText);
|
||||
});
|
||||
}
|
||||
|
||||
$('#login-form').on('submit', handleSubmit);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user