1
0
mirror of https://github.com/ascribe/onion.git synced 2025-01-03 10:25:08 +01:00

register first cut

This commit is contained in:
ddejongh 2015-06-22 10:50:22 +02:00
parent 23190f6c48
commit f836d4c2d4
8 changed files with 244 additions and 113 deletions

View File

@ -92,7 +92,14 @@ let Form = React.createClass({
this.setState({errors: []}); this.setState({errors: []});
}, },
getButtons() { getButtons() {
if (this.state.submitted){
return this.props.spinner;
}
if (this.props.buttons){
return this.props.buttons;
}
let buttons = null; let buttons = null;
if (this.state.edited){ if (this.state.edited){
buttons = ( buttons = (
<div className="pull-right"> <div className="pull-right">
@ -122,10 +129,12 @@ let Form = React.createClass({
}); });
}, },
render() { render() {
return ( return (
<form role="form" className="ascribe-form" onSubmit={this.submit} autoComplete="on"> <form role="form" className="ascribe-form" onSubmit={this.submit} autoComplete="on">
{this.getErrors()} {this.getErrors()}
{this.renderChildren()} {this.renderChildren()}
{this.getButtons()}
</form> </form>
); );

View File

@ -10,14 +10,12 @@ import Alt from '../alt';
import Nav from 'react-bootstrap/lib/Nav'; import Nav from 'react-bootstrap/lib/Nav';
import Navbar from 'react-bootstrap/lib/Navbar'; import Navbar from 'react-bootstrap/lib/Navbar';
import NavItem from 'react-bootstrap/lib/NavItem'; import CollapsibleNav from 'react-bootstrap/lib/CollapsibleNav';
import DropdownButton from 'react-bootstrap/lib/DropdownButton'; import DropdownButton from 'react-bootstrap/lib/DropdownButton';
import MenuItem from 'react-bootstrap/lib/MenuItem'; import MenuItem from 'react-bootstrap/lib/MenuItem';
import MenuItemLink from 'react-router-bootstrap/lib/MenuItemLink'; import MenuItemLink from 'react-router-bootstrap/lib/MenuItemLink';
import NavItemLink from 'react-router-bootstrap/lib/NavItemLink'; import NavItemLink from 'react-router-bootstrap/lib/NavItemLink';
import SignupModal from '../components/ascribe_modal/modal_signup';
import { getLangText } from '../utils/lang_utils'; import { getLangText } from '../utils/lang_utils';
@ -52,33 +50,33 @@ let Header = React.createClass({
if (this.state.currentUser.username){ if (this.state.currentUser.username){
account = ( account = (
<DropdownButton eventKey="1" title={this.state.currentUser.username}> <DropdownButton eventKey="1" title={this.state.currentUser.username}>
<MenuItemLink to="settings">{getLangText('Account Settings')}</MenuItemLink> <MenuItemLink to="settings">{getLangText('Account Settings')}</MenuItemLink>
<li className="divider"></li> <li className="divider"></li>
<MenuItem eventKey="2" href="/art/faq/">{getLangText('FAQ')}</MenuItem> <MenuItem eventKey="2" href="/art/faq/">{getLangText('FAQ')}</MenuItem>
<MenuItem eventKey="3" href="/art/terms/">{getLangText('Terms of Service')}</MenuItem> <MenuItem eventKey="3" href="/art/terms/">{getLangText('Terms of Service')}</MenuItem>
<MenuItem divider /> <MenuItem divider />
<MenuItem eventKey="4" onClick={this.handleLogout}>{getLangText('Log out')}</MenuItem> <MenuItem eventKey="4" onClick={this.handleLogout}>{getLangText('Log out')}</MenuItem>
</DropdownButton> </DropdownButton>
); );
} }
else { else {
account = <NavItemLink to="login">LOGIN</NavItemLink>; account = <NavItemLink to="login">LOGIN</NavItemLink>;
signup = ( signup = <NavItemLink to="signup">SIGNUP</NavItemLink>;
<SignupModal
button={<NavItem to="pieces">SIGNUP</NavItem>} />);
} }
return ( let brand = (<Link className="navbar-brand" to="pieces" path="/?page=1">
<Navbar>
<Nav>
<Link className="navbar-brand" to="pieces" path="/?page=1">
<span>ascribe </span> <span>ascribe </span>
<span className="glyph-ascribe-spool-chunked ascribe-color"></span> <span className="glyph-ascribe-spool-chunked ascribe-color"></span>
</Link> </Link>);
</Nav> return (
<Nav right>
{account} <Navbar brand={brand} toggleNavKey={0}>
{signup} <CollapsibleNav eventKey={0}>
</Nav> <Nav navbar />
<Nav navbar right>
{account}
{signup}
</Nav>
</CollapsibleNav>
</Navbar> </Navbar>
); );
} }

View File

@ -3,9 +3,6 @@
import React from 'react'; import React from 'react';
import Router from 'react-router'; import Router from 'react-router';
import UserActions from '../actions/user_actions';
import UserStore from '../stores/user_store';
import GlobalNotificationModel from '../models/global_notification_model'; import GlobalNotificationModel from '../models/global_notification_model';
import GlobalNotificationActions from '../actions/global_notification_actions'; import GlobalNotificationActions from '../actions/global_notification_actions';
@ -47,7 +44,16 @@ let LoginForm = React.createClass({
return ( return (
<Form <Form
url={apiUrls.users_login} url={apiUrls.users_login}
handleSuccess={this.handleSuccess}> handleSuccess={this.handleSuccess}
buttons={
<button type="submit" className="btn ascribe-btn ascribe-btn-login">
Log in to ascribe
</button>}
spinner={
<button className="btn ascribe-btn ascribe-btn-login ascribe-btn-login-spinner">
<img src="https://s3-us-west-2.amazonaws.com/ascribe0/media/thumbnails/ascribe_animated_medium.gif" />
</button>
}>
<Property <Property
name='email' name='email'
label="Email"> label="Email">
@ -71,9 +77,6 @@ let LoginForm = React.createClass({
Not an ascribe user&#63; Sign up...<br/> Not an ascribe user&#63; Sign up...<br/>
Forgot my password&#63; Rescue me... Forgot my password&#63; Rescue me...
</div> </div>
<button type="submit" className="btn ascribe-btn ascribe-btn-login">
Log in to ascribe
</button>
</Form> </Form>
); );
} }

View File

@ -5,74 +5,149 @@ import React from 'react';
import AppConstants from '../constants/application_constants'; import AppConstants from '../constants/application_constants';
import fineUploader from 'fineUploader'; import fineUploader from 'fineUploader';
import Router from 'react-router';
import GlobalNotificationModel from '../models/global_notification_model';
import GlobalNotificationActions from '../actions/global_notification_actions';
import Form from './ascribe_forms/form';
import Property from './ascribe_forms/property';
import apiUrls from '../constants/api_urls';
import ReactS3FineUploader from 'ReactS3FineUploader'; import ReactS3FineUploader from 'ReactS3FineUploader';
let RegisterPiece = React.createClass( { let RegisterPiece = React.createClass( {
render() { render() {
return ( return (
<div className="row ascribe-row">
<div> <div className="col-md-6">
<ReactS3FineUploader <FileUploader />
keyRoutine={{
url: AppConstants.serverUrl + 's3/key/',
fileClass: 'digitalwork'
}}
autoUpload={true}
debug={false}
objectProperties={{
acl: 'public-read',
bucket: 'ascribe0'
}}
request={{
endpoint: 'https://ascribe0.s3.amazonaws.com',
accessKey: 'AKIAIVCZJ33WSCBQ3QDA'
}}
signature={{
endpoint: AppConstants.serverUrl + 's3/signature/'
}}
uploadSuccess={{
params: {
isBrowserPreviewCapable: fineUploader.supportedFeatures.imagePreviews
}
}}
cors={{
expected: true
}}
chunking={{
enabled: true
}}
resume={{
enabled: true
}}
retry={{
enableAuto: false
}}
deleteFile={{
enabled: true,
method: 'DELETE',
endpoint: AppConstants.serverUrl + 's3/delete'
}}
validation={{
itemLimit: 100000,
sizeLimit: '25000000000'
}}
session={{
endpoint: null
}}
messages={{
unsupportedBrowser: '<h3>Upload is not functional in IE7 as IE7 has no support for CORS!</h3>'
}}
formatFileName={(name) => {// fix maybe
if (name !== undefined && name.length > 26) {
name = name.slice(0, 15) + '...' + name.slice(-15);
}
return name;
}}
multiple={true}/>
</div> </div>
<div className="col-md-6">
<LoginForm />
</div>
</div>
); );
} }
}); });
let FileUploader = React.createClass( {
render() {
return (
<ReactS3FineUploader
keyRoutine={{
url: AppConstants.serverUrl + 's3/key/',
fileClass: 'digitalwork'
}}
autoUpload={true}
debug={false}
objectProperties={{
acl: 'public-read',
bucket: 'ascribe0'
}}
request={{
endpoint: 'https://ascribe0.s3.amazonaws.com',
accessKey: 'AKIAIVCZJ33WSCBQ3QDA'
}}
signature={{
endpoint: AppConstants.serverUrl + 's3/signature/'
}}
uploadSuccess={{
params: {
isBrowserPreviewCapable: fineUploader.supportedFeatures.imagePreviews
}
}}
cors={{
expected: true
}}
chunking={{
enabled: true
}}
resume={{
enabled: true
}}
retry={{
enableAuto: false
}}
deleteFile={{
enabled: true,
method: 'DELETE',
endpoint: AppConstants.serverUrl + 's3/delete'
}}
validation={{
itemLimit: 100000,
sizeLimit: '25000000000'
}}
session={{
endpoint: null
}}
messages={{
unsupportedBrowser: '<h3>Upload is not functional in IE7 as IE7 has no support for CORS!</h3>'
}}
formatFileName={(name) => {// fix maybe
if (name !== undefined && name.length > 26) {
name = name.slice(0, 15) + '...' + name.slice(-15);
}
return name;
}}
multiple={true}/>
);
}
});
let LoginForm = React.createClass({
mixins: [Router.Navigation],
handleSuccess(){
let notification = new GlobalNotificationModel('Login successsful', 'success', 10000);
GlobalNotificationActions.appendGlobalNotification(notification);
this.transitionTo('pieces');
},
render() {
return (
<Form
url={apiUrls.users_login}
handleSuccess={this.handleSuccess}
buttons={
<button type="submit" className="btn ascribe-btn ascribe-btn-login">
Log in to ascribe
</button>}
spinner={
<button className="btn ascribe-btn ascribe-btn-login ascribe-btn-login-spinner">
<img src="https://s3-us-west-2.amazonaws.com/ascribe0/media/thumbnails/ascribe_animated_medium.gif" />
</button>
}>
<Property
name='email'
label="Email">
<input
type="email"
placeholder="Enter your email"
autoComplete="on"
required/>
</Property>
<Property
name='password'
label="Password">
<input
type="password"
placeholder="Enter your password"
autoComplete="on"
required/>
</Property>
<hr />
<div className="ascribe-login-text">
Not an ascribe user&#63; Sign up...<br/>
Forgot my password&#63; Rescue me...
</div>
</Form>
);
}
});
export default RegisterPiece; export default RegisterPiece;

View File

@ -14,31 +14,54 @@ import InputCheckbox from './ascribe_forms/input_checkbox';
import apiUrls from '../constants/api_urls'; import apiUrls from '../constants/api_urls';
let LoginContainer = React.createClass({ let SignupContainer = React.createClass({
mixins: [Router.Navigation], mixins: [Router.Navigation],
getInitialState(){
return ({
submitted: false,
message: null
});
},
handleSuccess(message){
this.setState({
submitted: true,
message: message
});
},
render() { render() {
if (this.state.submitted){
return (
<div className="ascribe-login-wrapper">
<br/>
<div className="ascribe-login-text ascribe-login-header">
{this.state.message}
</div>
</div>
);
}
return ( return (
<div className="ascribe-login-wrapper"> <div className="ascribe-login-wrapper">
<br/> <br/>
<div className="ascribe-login-text ascribe-login-header"> <div className="ascribe-login-text ascribe-login-header">
Welcome to ascribe... Welcome to ascribe...
</div> </div>
<LoginForm /> <SignupForm handleSuccess={this.handleSuccess}/>
</div> </div>
); );
} }
}); });
let LoginForm = React.createClass({ let SignupForm = React.createClass({
mixins: [Router.Navigation], mixins: [Router.Navigation],
handleSuccess(response){
handleSuccess(){ let notificationText = 'Sign up successful';
let notification = new GlobalNotificationModel('Login successsful', 'success', 10000); let notification = new GlobalNotificationModel(notificationText, 'success', 50000);
GlobalNotificationActions.appendGlobalNotification(notification); GlobalNotificationActions.appendGlobalNotification(notification);
this.transitionTo('pieces'); this.props.handleSuccess('We sent an email to your address ' + response.user.email + ', please confirm.');
}, },
render() { render() {
@ -47,8 +70,18 @@ let LoginForm = React.createClass({
'Store it in a safe place!'; 'Store it in a safe place!';
return ( return (
<Form <Form
url={apiUrls.users_login} ref='form'
handleSuccess={this.handleSuccess}> url={apiUrls.users_signup}
handleSuccess={this.handleSuccess}
buttons={
<button type="submit" className="btn ascribe-btn ascribe-btn-login">
Sign up to ascribe
</button>}
spinner={
<button className="btn ascribe-btn ascribe-btn-login ascribe-btn-login-spinner">
<img src="https://s3-us-west-2.amazonaws.com/ascribe0/media/thumbnails/ascribe_animated_medium.gif" />
</button>
}>
<Property <Property
name='email' name='email'
label="Email"> label="Email">
@ -58,15 +91,6 @@ let LoginForm = React.createClass({
autoComplete="on" autoComplete="on"
required/> required/>
</Property> </Property>
<Property
name='username'
label="Username">
<input
type="text"
placeholder="Choose a username"
autoComplete="on"
required/>
</Property>
<Property <Property
name='password' name='password'
label="Password" label="Password"
@ -89,26 +113,23 @@ let LoginForm = React.createClass({
</Property> </Property>
<Property <Property
name='promo_code' name='promo_code'
label="Promocode (Optional)"> label="Promocode">
<input <input
type="password" type="password"
placeholder="Enter a promocode here"/> placeholder="Enter a promocode here (Optional)"/>
</Property> </Property>
<hr />
<InputCheckbox <InputCheckbox
ref="terms" name='terms'
required="required" required="required"
label={ label={
<div> <div>
I agree to the&nbsp; I agree to the&nbsp;
<a href="/terms" target="_blank"> Terms of Service</a> <a href="/terms" target="_blank"> Terms of Service</a>
</div>}/> </div>}/>
<hr />
<button type="submit" className="btn ascribe-btn ascribe-btn-login">
Sign up to ascribe
</button>
</Form> </Form>
); );
} }
}); });
export default LoginContainer; export default SignupContainer;

View File

@ -1,5 +1,6 @@
$break-small: 764px; $break-small: 764px;
.ascribe-btn-login { .ascribe-btn-login {
padding: 1.5em; padding: 1.5em;
font-weight: 500; font-weight: 500;
@ -24,6 +25,21 @@ $break-small: 764px;
} }
} }
.ascribe-btn-login-spinner{
background-color: rgba(2, 182, 163, 0.4);
padding: 0.8em;
img {
height: 3em;
}
&:hover {
background-color: rgba(2, 182, 163, 0.4);
}
&:active, &:focus {
background-color: rgba(2, 182, 163, 0.4);
}
}
.ascribe-login-wrapper { .ascribe-login-wrapper {
width: 80%; width: 80%;
margin: 0 auto; margin: 0 auto;

View File

@ -0,0 +1,7 @@
$break-small: 764px;
.ascribe-row {
max-width: 600px;
margin: 0 auto
}

View File

@ -18,6 +18,7 @@ $BASE_URL: '<%= BASE_URL %>';
@import 'ascribe_textarea'; @import 'ascribe_textarea';
@import 'ascribe_media_player'; @import 'ascribe_media_player';
@import 'ascribe-global-notification'; @import 'ascribe-global-notification';
@import 'ascribe_piece_register';
@import 'offset_right'; @import 'offset_right';
@import 'ascribe_settings'; @import 'ascribe_settings';
@import '../node_modules/react-s3-fineuploader/scss/ascribe-theme'; @import '../node_modules/react-s3-fineuploader/scss/ascribe-theme';
@ -32,6 +33,7 @@ body {
} }
.navbar-default { .navbar-default {
border: none;
border-left:0; border-left:0;
border-right:0; border-right:0;
margin-bottom: 1.5em; margin-bottom: 1.5em;