Commit cc8fd8a946eb91032517986ddad90f0fe1bfd521
1 parent
6be49625fd
Exists in
master
Moved all files to respective folder and app is working without any errors
Showing
42 changed files
with
766 additions
and
666 deletions
Show diff stats
imports/client/components/validation.js
imports/client/layouts/InvalidOrgApp.js
... | ... | @@ -0,0 +1,18 @@ |
1 | +import React from 'react'; | |
2 | +import { Grid } from 'react-bootstrap'; | |
3 | +import AppNavigation from '../containers/AppNavigation.js'; | |
4 | + | |
5 | +const App = ({ children }) => ( | |
6 | + <div> | |
7 | + <AppNavigation /> | |
8 | + <Grid> | |
9 | + { children } | |
10 | + </Grid> | |
11 | + </div> | |
12 | +); | |
13 | + | |
14 | +App.propTypes = { | |
15 | + children: React.PropTypes.node, | |
16 | +}; | |
17 | + | |
18 | +export default App; | ... | ... |
imports/client/layouts/NonOrgApp.js
... | ... | @@ -0,0 +1,18 @@ |
1 | +import React from 'react'; | |
2 | +import { Grid } from 'react-bootstrap'; | |
3 | +import AppNavigation from '../containers/AppNavigation.js'; | |
4 | + | |
5 | +const App = ({ children }) => ( | |
6 | + <div> | |
7 | + <AppNavigation /> | |
8 | + <Grid> | |
9 | + { children } | |
10 | + </Grid> | |
11 | + </div> | |
12 | +); | |
13 | + | |
14 | +App.propTypes = { | |
15 | + children: React.PropTypes.node, | |
16 | +}; | |
17 | + | |
18 | +export default App; | ... | ... |
imports/client/layouts/OrgApp.js
... | ... | @@ -0,0 +1,18 @@ |
1 | +import React from 'react'; | |
2 | +import { Grid } from 'react-bootstrap'; | |
3 | +import AppNavigation from '/imports/client/views/app/module/navigation/AppNavigation'; | |
4 | + | |
5 | +const App = ({ children }) => ( | |
6 | + <div> | |
7 | + <AppNavigation /> | |
8 | + <Grid> | |
9 | + { children } | |
10 | + </Grid> | |
11 | + </div> | |
12 | +); | |
13 | + | |
14 | +App.propTypes = { | |
15 | + children: React.PropTypes.node, | |
16 | +}; | |
17 | + | |
18 | +export default App; | ... | ... |
imports/client/views/app/module/Index.js
... | ... | @@ -0,0 +1,15 @@ |
1 | +import React from 'react'; | |
2 | +import { Jumbotron } from 'react-bootstrap'; | |
3 | + | |
4 | +const Index = () => ( | |
5 | + <div className="Index"> | |
6 | + <Jumbotron className="text-center"> | |
7 | + <h2>Base</h2> | |
8 | + <p>A starting point for Meteor applications.</p> | |
9 | + <p><a className="btn btn-success" href="https://themeteorchef.com/base" role="button">Read the Documentation</a></p> | |
10 | + <p style={ { fontSize: '16px', color: '#aaa' } }>Currently at v4.11.1</p> | |
11 | + </Jumbotron> | |
12 | + </div> | |
13 | +); | |
14 | + | |
15 | +export default Index; | ... | ... |
imports/client/views/app/module/navigation/AppNavigation.js
... | ... | @@ -0,0 +1,27 @@ |
1 | +import React from 'react'; | |
2 | +import { Navbar } from 'react-bootstrap'; | |
3 | +import { Link } from 'react-router'; | |
4 | +import PublicNavigation from './PublicNavigation.js'; | |
5 | +import AuthenticatedNavigation from './AuthenticatedNavigation.js'; | |
6 | + | |
7 | +const renderNavigation = hasUser => (hasUser ? <AuthenticatedNavigation /> : <PublicNavigation />); | |
8 | + | |
9 | +const AppNavigation = ({ hasUser }) => ( | |
10 | + <Navbar> | |
11 | + <Navbar.Header> | |
12 | + <Navbar.Brand> | |
13 | + <Link to="/">Application Name</Link> | |
14 | + </Navbar.Brand> | |
15 | + <Navbar.Toggle /> | |
16 | + </Navbar.Header> | |
17 | + <Navbar.Collapse> | |
18 | + { renderNavigation(hasUser) } | |
19 | + </Navbar.Collapse> | |
20 | + </Navbar> | |
21 | +); | |
22 | + | |
23 | +AppNavigation.propTypes = { | |
24 | + hasUser: React.PropTypes.object, | |
25 | +}; | |
26 | + | |
27 | +export default AppNavigation; | ... | ... |
imports/client/views/app/module/navigation/AuthenticatedNavigation.js
... | ... | @@ -0,0 +1,30 @@ |
1 | +import React from 'react'; | |
2 | +import { browserHistory } from 'react-router'; | |
3 | +import { LinkContainer } from 'react-router-bootstrap'; | |
4 | +import { Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap'; | |
5 | +import { Meteor } from 'meteor/meteor'; | |
6 | + | |
7 | +const handleLogout = () => Meteor.logout(() => browserHistory.push('/login')); | |
8 | + | |
9 | +const userName = () => { | |
10 | + const user = Meteor.user(); | |
11 | + const name = user && user.profile ? user.profile.name : ''; | |
12 | + return user ? `${name.first} ${name.last}` : ''; | |
13 | +}; | |
14 | + | |
15 | +const AuthenticatedNavigation = () => ( | |
16 | + <div> | |
17 | + <Nav> | |
18 | + <LinkContainer to="/documents"> | |
19 | + <NavItem eventKey={ 2 } href="/documents">Documents</NavItem> | |
20 | + </LinkContainer> | |
21 | + </Nav> | |
22 | + <Nav pullRight> | |
23 | + <NavDropdown eventKey={ 3 } title={ userName() } id="basic-nav-dropdown"> | |
24 | + <MenuItem eventKey={ 3.1 } onClick={ handleLogout }>Logout</MenuItem> | |
25 | + </NavDropdown> | |
26 | + </Nav> | |
27 | + </div> | |
28 | +); | |
29 | + | |
30 | +export default AuthenticatedNavigation; | ... | ... |
imports/client/views/app/module/navigation/Loading.js
... | ... | @@ -0,0 +1,30 @@ |
1 | +import React from 'react'; | |
2 | + | |
3 | +const Loading = () => ( | |
4 | + <svg | |
5 | + version="1.1" | |
6 | + className="Loading" | |
7 | + xmlns="http://www.w3.org/2000/svg" | |
8 | + x="0px" | |
9 | + y="0px" | |
10 | + width="40px" | |
11 | + height="40px" | |
12 | + viewBox="0 0 40 40" | |
13 | + enableBackground="new 0 0 40 40"> | |
14 | + <path | |
15 | + opacity="1.0" | |
16 | + fill="#eee" | |
17 | + d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946, | |
18 | + 14.946,14.946s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201, | |
19 | + 5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634c0-6.425, | |
20 | + 5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834, | |
21 | + 26.541,26.626,31.749,20.201,31.749z"/> | |
22 | + <path | |
23 | + fill="#da5347" | |
24 | + d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0 | |
25 | + C22.32,8.481,24.301,9.057,26.013,10.047z"> | |
26 | + </path> | |
27 | + </svg> | |
28 | +); | |
29 | + | |
30 | +export default Loading; | ... | ... |
imports/client/views/app/module/navigation/PublicNavigation.js
... | ... | @@ -0,0 +1,16 @@ |
1 | +import React from 'react'; | |
2 | +import { LinkContainer } from 'react-router-bootstrap'; | |
3 | +import { Nav, NavItem } from 'react-bootstrap'; | |
4 | + | |
5 | +const PublicNavigation = () => ( | |
6 | + <Nav pullRight> | |
7 | + <LinkContainer to="signup"> | |
8 | + <NavItem eventKey={ 1 } href="/signup">Sign Up</NavItem> | |
9 | + </LinkContainer> | |
10 | + <LinkContainer to="login"> | |
11 | + <NavItem eventKey={ 2 } href="/login">Log In</NavItem> | |
12 | + </LinkContainer> | |
13 | + </Nav> | |
14 | +); | |
15 | + | |
16 | +export default PublicNavigation; | ... | ... |
imports/client/views/app/module/navigation/index.js
... | ... | @@ -0,0 +1,7 @@ |
1 | +import { composeWithTracker } from 'react-komposer'; | |
2 | +import { Meteor } from 'meteor/meteor'; | |
3 | +import AppNavigation from '../components/AppNavigation.js'; | |
4 | + | |
5 | +const composer = (props, onData) => onData(null, { hasUser: Meteor.user() }); | |
6 | + | |
7 | +export default composeWithTracker(composer, {}, {}, { pure: false })(AppNavigation); | ... | ... |
imports/client/views/invalidOrg/NotFound.js
... | ... | @@ -0,0 +1,12 @@ |
1 | +import React from 'react'; | |
2 | +import { Alert } from 'react-bootstrap'; | |
3 | + | |
4 | +const NotFound = () => ( | |
5 | + <div className="NotFound"> | |
6 | + <Alert bsStyle="danger"> | |
7 | + <p><strong>Error [404]</strong>: { window.location.pathname } does not exist.</p> | |
8 | + </Alert> | |
9 | + </div> | |
10 | +); | |
11 | + | |
12 | +export default NotFound; | ... | ... |
imports/client/views/nonOrg/NotFound.js
... | ... | @@ -0,0 +1,12 @@ |
1 | +import React from 'react'; | |
2 | +import { Alert } from 'react-bootstrap'; | |
3 | + | |
4 | +const NotFound = () => ( | |
5 | + <div className="NotFound"> | |
6 | + <Alert bsStyle="danger"> | |
7 | + <p><strong>Error [404]</strong>: { window.location.pathname } does not exist.</p> | |
8 | + </Alert> | |
9 | + </div> | |
10 | +); | |
11 | + | |
12 | +export default NotFound; | ... | ... |
imports/client/views/nonOrg/enter/SignupView.js
... | ... | @@ -0,0 +1,116 @@ |
1 | +import React from 'react'; | |
2 | +import { Link } from 'react-router'; | |
3 | +import { Row, Col, FormGroup, | |
4 | + ControlLabel, FormControl, | |
5 | + InputGroup, Button } from 'react-bootstrap'; | |
6 | +import handleSignup from './signup'; | |
7 | +import { Orgs } from '/imports/collections/orgs/index'; | |
8 | + | |
9 | +export default class Signup extends React.Component { | |
10 | + constructor(props) { | |
11 | + super(props); | |
12 | + this.state = { | |
13 | + orgSlug: "" | |
14 | + }; | |
15 | + } | |
16 | + componentWillMount(){ | |
17 | + Meteor.subscribe('allOrgsSlug'); | |
18 | + } | |
19 | + | |
20 | + componentDidMount() { | |
21 | + handleSignup({ component: this }); | |
22 | + } | |
23 | + handleChange(e) { | |
24 | + this.setState({ orgSlug: e.target.value }); | |
25 | + } | |
26 | + handleSubmit(event) { | |
27 | + event.preventDefault(); | |
28 | + } | |
29 | + checkExistingOrgSlug() { | |
30 | + console.log(this.state.orgSlug); | |
31 | + if(this.state.orgSlug==""){return null} | |
32 | + searchOrg = Orgs.find({slug:this.state.orgSlug}).fetch(); | |
33 | + if(searchOrg.length>0){ | |
34 | + return "error" | |
35 | + }else{ | |
36 | + return "success" | |
37 | + } | |
38 | + } | |
39 | + render() { | |
40 | + return ( | |
41 | + <div className="Signup"> | |
42 | + <Row> | |
43 | + <Col xs={ 12 } sm={ 6 } md={ 4 }> | |
44 | + <h4 className="page-header">Sign Up</h4> | |
45 | + <form | |
46 | + ref={ form => (this.signupForm = form) } | |
47 | + onSubmit={ this.handleSubmit } | |
48 | + > | |
49 | + <Row> | |
50 | + <Col xs={ 12 } sm={ 12 }> | |
51 | + <FormGroup controlId="orgSlugField" validationState={this.checkExistingOrgSlug()}> | |
52 | + <ControlLabel>Organisation name</ControlLabel> | |
53 | + <InputGroup> | |
54 | + <FormControl | |
55 | + type ="text" | |
56 | + ref ="orgSlug" | |
57 | + name ="orgSlug" | |
58 | + placeholder ="School Name" | |
59 | + onChange = {(e) => this.handleChange(e)} | |
60 | + /> | |
61 | + <InputGroup.Addon>@yd.com</InputGroup.Addon> | |
62 | + </InputGroup> | |
63 | + </FormGroup> | |
64 | + </Col> | |
65 | + </Row> | |
66 | + <Row> | |
67 | + <Col xs={ 6 } sm={ 6 }> | |
68 | + <FormGroup> | |
69 | + <ControlLabel>First Name</ControlLabel> | |
70 | + <FormControl | |
71 | + type="text" | |
72 | + ref="firstName" | |
73 | + name="firstName" | |
74 | + placeholder="First Name" | |
75 | + /> | |
76 | + </FormGroup> | |
77 | + </Col> | |
78 | + <Col xs={ 6 } sm={ 6 }> | |
79 | + <FormGroup> | |
80 | + <ControlLabel>Last Name</ControlLabel> | |
81 | + <FormControl | |
82 | + type="text" | |
83 | + ref="lastName" | |
84 | + name="lastName" | |
85 | + placeholder="Last Name" | |
86 | + /> | |
87 | + </FormGroup> | |
88 | + </Col> | |
89 | + </Row> | |
90 | + <FormGroup> | |
91 | + <ControlLabel>Email Address</ControlLabel> | |
92 | + <FormControl | |
93 | + type="text" | |
94 | + ref="emailAddress" | |
95 | + name="emailAddress" | |
96 | + placeholder="Email Address" | |
97 | + /> | |
98 | + </FormGroup> | |
99 | + <FormGroup> | |
100 | + <ControlLabel>Password</ControlLabel> | |
101 | + <FormControl | |
102 | + type="password" | |
103 | + ref="password" | |
104 | + name="password" | |
105 | + placeholder="Password" | |
106 | + /> | |
107 | + </FormGroup> | |
108 | + <Button type="submit" bsStyle="success">Sign Up</Button> | |
109 | + </form> | |
110 | + <p>Already have an account? <Link to="/login">Log In</Link>.</p> | |
111 | + </Col> | |
112 | + </Row> | |
113 | + </div> | |
114 | + ); | |
115 | + } | |
116 | +} | ... | ... |
imports/client/views/nonOrg/enter/signup.js
... | ... | @@ -0,0 +1,97 @@ |
1 | +/* eslint-disable no-undef */ | |
2 | + | |
3 | +import { browserHistory } from 'react-router'; | |
4 | +import { Accounts } from 'meteor/accounts-base'; | |
5 | +import { Bert } from 'meteor/themeteorchef:bert'; | |
6 | +import { Loading } from '/imports/client/components/Loading'; | |
7 | +import '/imports/client/components/validation'; | |
8 | +import { Orgs } from '/imports/collections/orgs/index'; | |
9 | + | |
10 | +let component; | |
11 | + | |
12 | +const getUserData = () => ({ | |
13 | + email: document.querySelector('[name="emailAddress"]').value, | |
14 | + password: document.querySelector('[name="password"]').value, | |
15 | + profile: { | |
16 | + name: { | |
17 | + first: document.querySelector('[name="firstName"]').value, | |
18 | + last: document.querySelector('[name="lastName"]').value, | |
19 | + }, | |
20 | + }, | |
21 | +}); | |
22 | + | |
23 | +const signup = () => { | |
24 | + const user = getUserData(); | |
25 | + | |
26 | + Accounts.createUser(user, (error) => { | |
27 | + if (error) { | |
28 | + Bert.alert(error.reason, 'danger'); | |
29 | + } else { | |
30 | + browserHistory.push('/'); | |
31 | + Bert.alert('Welcome!', 'success'); | |
32 | + } | |
33 | + }); | |
34 | +}; | |
35 | +$.validator.addMethod( | |
36 | + "uniqueSlug", | |
37 | + function(value, element) { | |
38 | + slug = Orgs.find({slug:value}).fetch(); | |
39 | + console.log(slug); | |
40 | + if(slug.length>0){ | |
41 | + return false; | |
42 | + }else{ | |
43 | + return true | |
44 | + } | |
45 | + }, | |
46 | + "Name is Already Taken" | |
47 | +); | |
48 | +const validate = () => { | |
49 | + $(component.signupForm).validate({ | |
50 | + rules: { | |
51 | + orgSlug: { | |
52 | + required: true, | |
53 | + uniqueSlug: true | |
54 | + }, | |
55 | + firstName: { | |
56 | + required: true, | |
57 | + }, | |
58 | + lastName: { | |
59 | + required: true, | |
60 | + }, | |
61 | + emailAddress: { | |
62 | + required: true, | |
63 | + email: true, | |
64 | + }, | |
65 | + password: { | |
66 | + required: true, | |
67 | + minlength: 6, | |
68 | + }, | |
69 | + }, | |
70 | + messages: { | |
71 | + orgSlug: { | |
72 | + required: 'Choose your school url', | |
73 | + uniqueSlug: 'This has already been taken!' | |
74 | + }, | |
75 | + firstName: { | |
76 | + required: 'First name?', | |
77 | + }, | |
78 | + lastName: { | |
79 | + required: 'Last name?', | |
80 | + }, | |
81 | + emailAddress: { | |
82 | + required: 'Need an email address here.', | |
83 | + email: 'Is this email address legit?', | |
84 | + }, | |
85 | + password: { | |
86 | + required: 'Need a password here.', | |
87 | + minlength: 'Use at least six characters, please.', | |
88 | + }, | |
89 | + }, | |
90 | + submitHandler() { signup(); }, | |
91 | + }); | |
92 | +}; | |
93 | + | |
94 | +export default function handleSignup(options) { | |
95 | + component = options.component; | |
96 | + validate(); | |
97 | +} | ... | ... |
imports/client/views/org/NotFound.js
... | ... | @@ -0,0 +1,12 @@ |
1 | +import React from 'react'; | |
2 | +import { Alert } from 'react-bootstrap'; | |
3 | + | |
4 | +const NotFound = () => ( | |
5 | + <div className="NotFound"> | |
6 | + <Alert bsStyle="danger"> | |
7 | + <p><strong>Error [404]</strong>: { window.location.pathname } does not exist.</p> | |
8 | + </Alert> | |
9 | + </div> | |
10 | +); | |
11 | + | |
12 | +export default NotFound; | ... | ... |
imports/client/views/org/enter/Login.js
... | ... | @@ -0,0 +1,54 @@ |
1 | +import React from 'react'; | |
2 | +import { Link } from 'react-router'; | |
3 | +import { Row, Col, FormGroup, ControlLabel, FormControl, Button } from 'react-bootstrap'; | |
4 | +import handleLogin from './module/login'; | |
5 | + | |
6 | +export default class Login extends React.Component { | |
7 | + componentDidMount() { | |
8 | + handleLogin({ component: this }); | |
9 | + } | |
10 | + | |
11 | + handleSubmit(event) { | |
12 | + event.preventDefault(); | |
13 | + } | |
14 | + | |
15 | + render() { | |
16 | + return ( | |
17 | + <div className="Login"> | |
18 | + <Row> | |
19 | + <Col xs={ 12 } sm={ 6 } md={ 4 }> | |
20 | + <h4 className="page-header">Login</h4> | |
21 | + <form | |
22 | + ref={ form => (this.loginForm = form) } | |
23 | + className="login" | |
24 | + onSubmit={ this.handleSubmit } | |
25 | + > | |
26 | + <FormGroup> | |
27 | + <ControlLabel>Email Address</ControlLabel> | |
28 | + <FormControl | |
29 | + type="email" | |
30 | + ref="emailAddress" | |
31 | + name="emailAddress" | |
32 | + placeholder="Email Address" | |
33 | + /> | |
34 | + </FormGroup> | |
35 | + <FormGroup> | |
36 | + <ControlLabel> | |
37 | + <span className="pull-left">Password</span> | |
38 | + <Link className="pull-right" to="/recover-password">Forgot Password?</Link> | |
39 | + </ControlLabel> | |
40 | + <FormControl | |
41 | + type="password" | |
42 | + ref="password" | |
43 | + name="password" | |
44 | + placeholder="Password" | |
45 | + /> | |
46 | + </FormGroup> | |
47 | + <Button type="submit" bsStyle="success">Login</Button> | |
48 | + </form> | |
49 | + </Col> | |
50 | + </Row> | |
51 | + </div> | |
52 | + ); | |
53 | + } | |
54 | +} | ... | ... |
imports/client/views/org/enter/RecoverPassword.js
... | ... | @@ -0,0 +1,43 @@ |
1 | +import React from 'react'; | |
2 | +import { Row, Col, Alert, FormGroup, FormControl, Button } from 'react-bootstrap'; | |
3 | +import handleRecoverPassword from './module/recover-password'; | |
4 | + | |
5 | +export default class RecoverPassword extends React.Component { | |
6 | + componentDidMount() { | |
7 | + handleRecoverPassword({ component: this }); | |
8 | + } | |
9 | + | |
10 | + handleSubmit(event) { | |
11 | + event.preventDefault(); | |
12 | + } | |
13 | + | |
14 | + render() { | |
15 | + return ( | |
16 | + <div className="RecoverPassword"> | |
17 | + <Row> | |
18 | + <Col xs={ 12 } sm={ 6 } md={ 4 }> | |
19 | + <h4 className="page-header">Recover Password</h4> | |
20 | + <Alert bsStyle="info"> | |
21 | + Enter your email address below to receive a link to reset your password. | |
22 | + </Alert> | |
23 | + <form | |
24 | + ref={ form => (this.recoverPasswordForm = form) } | |
25 | + className="recover-password" | |
26 | + onSubmit={ this.handleSubmit } | |
27 | + > | |
28 | + <FormGroup> | |
29 | + <FormControl | |
30 | + type="email" | |
31 | + ref="emailAddress" | |
32 | + name="emailAddress" | |
33 | + placeholder="Email Address" | |
34 | + /> | |
35 | + </FormGroup> | |
36 | + <Button type="submit" bsStyle="success">Recover Password</Button> | |
37 | + </form> | |
38 | + </Col> | |
39 | + </Row> | |
40 | + </div> | |
41 | + ); | |
42 | + } | |
43 | +} | ... | ... |
imports/client/views/org/enter/ResetPassword.js
... | ... | @@ -0,0 +1,58 @@ |
1 | +import React from 'react'; | |
2 | +import { Row, Col, Alert, FormGroup, ControlLabel, FormControl, Button } from 'react-bootstrap'; | |
3 | +import handleResetPassword from './module/reset-password'; | |
4 | + | |
5 | +export default class ResetPassword extends React.Component { | |
6 | + componentDidMount() { | |
7 | + handleResetPassword({ component: this, token: this.props.params.token }); | |
8 | + } | |
9 | + | |
10 | + handleSubmit(event) { | |
11 | + event.preventDefault(); | |
12 | + } | |
13 | + | |
14 | + render() { | |
15 | + return ( | |
16 | + <div className="ResetPassword"> | |
17 | + <Row> | |
18 | + <Col xs={ 12 } sm={ 6 } md={ 4 }> | |
19 | + <h4 className="page-header">Reset Password</h4> | |
20 | + <Alert bsStyle="info"> | |
21 | + To reset your password, enter a new one below. You will be logged in | |
22 | + with your new password. | |
23 | + </Alert> | |
24 | + <form | |
25 | + ref={ form => (this.resetPasswordForm = form) } | |
26 | + className="reset-password" | |
27 | + onSubmit={ this.handleSubmit } | |
28 | + > | |
29 | + <FormGroup> | |
30 | + <ControlLabel>New Password</ControlLabel> | |
31 | + <FormControl | |
32 | + type="password" | |
33 | + ref="newPassword" | |
34 | + name="newPassword" | |
35 | + placeholder="New Password" | |
36 | + /> | |
37 | + </FormGroup> | |
38 | + <FormGroup> | |
39 | + <ControlLabel>Repeat New Password</ControlLabel> | |
40 | + <FormControl | |
41 | + type="password" | |
42 | + ref="repeatNewPassword" | |
43 | + name="repeatNewPassword" | |
44 | + placeholder="Repeat New Password" | |
45 | + /> | |
46 | + </FormGroup> | |
47 | + <Button type="submit" bsStyle="success">Reset Password & Login</Button> | |
48 | + </form> | |
49 | + </Col> | |
50 | + </Row> | |
51 | + </div> | |
52 | + ); | |
53 | + } | |
54 | +} | |
55 | + | |
56 | +ResetPassword.propTypes = { | |
57 | + params: React.PropTypes.object, | |
58 | +}; | ... | ... |
imports/client/views/org/enter/module/login.js
... | ... | @@ -0,0 +1,57 @@ |
1 | +/* eslint-disable no-undef */ | |
2 | + | |
3 | +import { browserHistory } from 'react-router'; | |
4 | +import { Meteor } from 'meteor/meteor'; | |
5 | +import { Bert } from 'meteor/themeteorchef:bert'; | |
6 | +import '/imports/client/components/validation'; | |
7 | + | |
8 | +let component; | |
9 | + | |
10 | +const login = () => { | |
11 | + const email = document.querySelector('[name="emailAddress"]').value; | |
12 | + const password = document.querySelector('[name="password"]').value; | |
13 | + | |
14 | + Meteor.loginWithPassword(email, password, (error) => { | |
15 | + if (error) { | |
16 | + Bert.alert(error.reason, 'warning'); | |
17 | + } else { | |
18 | + Bert.alert('Logged in!', 'success'); | |
19 | + | |
20 | + const { location } = component.props; | |
21 | + if (location.state && location.state.nextPathname) { | |
22 | + browserHistory.push(location.state.nextPathname); | |
23 | + } else { | |
24 | + browserHistory.push('/'); | |
25 | + } | |
26 | + } | |
27 | + }); | |
28 | +}; | |
29 | + | |
30 | +const validate = () => { | |
31 | + $(component.loginForm).validate({ | |
32 | + rules: { | |
33 | + emailAddress: { | |
34 | + required: true, | |
35 | + email: true, | |
36 | + }, | |
37 | + password: { | |
38 | + required: true, | |
39 | + }, | |
40 | + }, | |
41 | + messages: { | |
42 | + emailAddress: { | |
43 | + required: 'Need an email address here.', | |
44 | + email: 'Is this email address legit?', | |
45 | + }, | |
46 | + password: { | |
47 | + required: 'Need a password here.', | |
48 | + }, | |
49 | + }, | |
50 | + submitHandler() { login(); }, | |
51 | + }); | |
52 | +}; | |
53 | + | |
54 | +export default function handleLogin(options) { | |
55 | + component = options.component; | |
56 | + validate(); | |
57 | +} | ... | ... |
imports/client/views/org/enter/module/recover-password.js
... | ... | @@ -0,0 +1,42 @@ |
1 | +/* eslint-disable no-undef */ | |
2 | + | |
3 | +import { Accounts } from 'meteor/accounts-base'; | |
4 | +import { Bert } from 'meteor/themeteorchef:bert'; | |
5 | +import '/imports/client/components/validation'; | |
6 | + | |
7 | +let component; | |
8 | + | |
9 | +const handleRecovery = () => { | |
10 | + Accounts.forgotPassword({ | |
11 | + email: document.querySelector('[name="emailAddress"]').value, | |
12 | + }, (error) => { | |
13 | + if (error) { | |
14 | + Bert.alert(error.reason, 'warning'); | |
15 | + } else { | |
16 | + Bert.alert('Check your inbox for a reset link!', 'success'); | |
17 | + } | |
18 | + }); | |
19 | +}; | |
20 | + | |
21 | +const validate = () => { | |
22 | + $(component.recoverPasswordForm).validate({ | |
23 | + rules: { | |
24 | + emailAddress: { | |
25 | + required: true, | |
26 | + email: true, | |
27 | + }, | |
28 | + }, | |
29 | + messages: { | |
30 | + emailAddress: { | |
31 | + required: 'Need an email address here.', | |
32 | + email: 'Is this email address legit?', | |
33 | + }, | |
34 | + }, | |
35 | + submitHandler() { handleRecovery(); }, | |
36 | + }); | |
37 | +}; | |
38 | + | |
39 | +export default function handleRecoverPassword(options) { | |
40 | + component = options.component; | |
41 | + validate(); | |
42 | +} | ... | ... |
imports/client/views/org/enter/module/reset-password.js
... | ... | @@ -0,0 +1,54 @@ |
1 | +/* eslint-disable no-undef */ | |
2 | + | |
3 | +import { browserHistory } from 'react-router'; | |
4 | +import { Accounts } from 'meteor/accounts-base'; | |
5 | +import { Bert } from 'meteor/themeteorchef:bert'; | |
6 | +import '/imports/client/components/validation'; | |
7 | + | |
8 | +let component; | |
9 | +let token; | |
10 | + | |
11 | +const handleReset = () => { | |
12 | + const password = document.querySelector('[name="newPassword"]').value; | |
13 | + Accounts.resetPassword(token, password, (error) => { | |
14 | + if (error) { | |
15 | + Bert.alert(error.reason, 'danger'); | |
16 | + } else { | |
17 | + browserHistory.push('/'); | |
18 | + Bert.alert('Password reset!', 'success'); | |
19 | + } | |
20 | + }); | |
21 | +}; | |
22 | + | |
23 | +const validate = () => { | |
24 | + $(component.resetPasswordForm).validate({ | |
25 | + rules: { | |
26 | + newPassword: { | |
27 | + required: true, | |
28 | + minlength: 6, | |
29 | + }, | |
30 | + repeatNewPassword: { | |
31 | + required: true, | |
32 | + minlength: 6, | |
33 | + equalTo: '[name="newPassword"]', | |
34 | + }, | |
35 | + }, | |
36 | + messages: { | |
37 | + newPassword: { | |
38 | + required: 'Enter a new password, please.', | |
39 | + minlength: 'Use at least six characters, please.', | |
40 | + }, | |
41 | + repeatNewPassword: { | |
42 | + required: 'Repeat your new password, please.', | |
43 | + equalTo: 'Hmm, your passwords don\'t match. Try again?', | |
44 | + }, | |
45 | + }, | |
46 | + submitHandler() { handleReset(); }, | |
47 | + }); | |
48 | +}; | |
49 | + | |
50 | +export default function handleResetPassword(options) { | |
51 | + component = options.component; | |
52 | + token = options.token; | |
53 | + validate(); | |
54 | +} | ... | ... |
imports/collections/orgs/methods.js
imports/modules/login.js
... | ... | @@ -1,57 +0,0 @@ |
1 | -/* eslint-disable no-undef */ | |
2 | - | |
3 | -import { browserHistory } from 'react-router'; | |
4 | -import { Meteor } from 'meteor/meteor'; | |
5 | -import { Bert } from 'meteor/themeteorchef:bert'; | |
6 | -import './validation.js'; | |
7 | - | |
8 | -let component; | |
9 | - | |
10 | -const login = () => { | |
11 | - const email = document.querySelector('[name="emailAddress"]').value; | |
12 | - const password = document.querySelector('[name="password"]').value; | |
13 | - | |
14 | - Meteor.loginWithPassword(email, password, (error) => { | |
15 | - if (error) { | |
16 | - Bert.alert(error.reason, 'warning'); | |
17 | - } else { | |
18 | - Bert.alert('Logged in!', 'success'); | |
19 | - | |
20 | - const { location } = component.props; | |
21 | - if (location.state && location.state.nextPathname) { | |
22 | - browserHistory.push(location.state.nextPathname); | |
23 | - } else { | |
24 | - browserHistory.push('/'); | |
25 | - } | |
26 | - } | |
27 | - }); | |
28 | -}; | |
29 | - | |
30 | -const validate = () => { | |
31 | - $(component.loginForm).validate({ | |
32 | - rules: { | |
33 | - emailAddress: { | |
34 | - required: true, | |
35 | - email: true, | |
36 | - }, | |
37 | - password: { | |
38 | - required: true, | |
39 | - }, | |
40 | - }, | |
41 | - messages: { | |
42 | - emailAddress: { | |
43 | - required: 'Need an email address here.', | |
44 | - email: 'Is this email address legit?', | |
45 | - }, | |
46 | - password: { | |
47 | - required: 'Need a password here.', | |
48 | - }, | |
49 | - }, | |
50 | - submitHandler() { login(); }, | |
51 | - }); | |
52 | -}; | |
53 | - | |
54 | -export default function handleLogin(options) { | |
55 | - component = options.component; | |
56 | - validate(); | |
57 | -} |
imports/modules/recover-password.js
... | ... | @@ -1,42 +0,0 @@ |
1 | -/* eslint-disable no-undef */ | |
2 | - | |
3 | -import { Accounts } from 'meteor/accounts-base'; | |
4 | -import { Bert } from 'meteor/themeteorchef:bert'; | |
5 | -import './validation.js'; | |
6 | - | |
7 | -let component; | |
8 | - | |
9 | -const handleRecovery = () => { | |
10 | - Accounts.forgotPassword({ | |
11 | - email: document.querySelector('[name="emailAddress"]').value, | |
12 | - }, (error) => { | |
13 | - if (error) { | |
14 | - Bert.alert(error.reason, 'warning'); | |
15 | - } else { | |
16 | - Bert.alert('Check your inbox for a reset link!', 'success'); | |
17 | - } | |
18 | - }); | |
19 | -}; | |
20 | - | |
21 | -const validate = () => { | |
22 | - $(component.recoverPasswordForm).validate({ | |
23 | - rules: { | |
24 | - emailAddress: { | |
25 | - required: true, | |
26 | - email: true, | |
27 | - }, | |
28 | - }, | |
29 | - messages: { | |
30 | - emailAddress: { | |
31 | - required: 'Need an email address here.', | |
32 | - email: 'Is this email address legit?', | |
33 | - }, | |
34 | - }, | |
35 | - submitHandler() { handleRecovery(); }, | |
36 | - }); | |
37 | -}; | |
38 | - | |
39 | -export default function handleRecoverPassword(options) { | |
40 | - component = options.component; | |
41 | - validate(); | |
42 | -} |
imports/modules/reset-password.js
... | ... | @@ -1,54 +0,0 @@ |
1 | -/* eslint-disable no-undef */ | |
2 | - | |
3 | -import { browserHistory } from 'react-router'; | |
4 | -import { Accounts } from 'meteor/accounts-base'; | |
5 | -import { Bert } from 'meteor/themeteorchef:bert'; | |
6 | -import './validation.js'; | |
7 | - | |
8 | -let component; | |
9 | -let token; | |
10 | - | |
11 | -const handleReset = () => { | |
12 | - const password = document.querySelector('[name="newPassword"]').value; | |
13 | - Accounts.resetPassword(token, password, (error) => { | |
14 | - if (error) { | |
15 | - Bert.alert(error.reason, 'danger'); | |
16 | - } else { | |
17 | - browserHistory.push('/'); | |
18 | - Bert.alert('Password reset!', 'success'); | |
19 | - } | |
20 | - }); | |
21 | -}; | |
22 | - | |
23 | -const validate = () => { | |
24 | - $(component.resetPasswordForm).validate({ | |
25 | - rules: { | |
26 | - newPassword: { | |
27 | - required: true, | |
28 | - minlength: 6, | |
29 | - }, | |
30 | - repeatNewPassword: { | |
31 | - required: true, | |
32 | - minlength: 6, | |
33 | - equalTo: '[name="newPassword"]', | |
34 | - }, | |
35 | - }, | |
36 | - messages: { | |
37 | - newPassword: { | |
38 | - required: 'Enter a new password, please.', | |
39 | - minlength: 'Use at least six characters, please.', | |
40 | - }, | |
41 | - repeatNewPassword: { | |
42 | - required: 'Repeat your new password, please.', | |
43 | - equalTo: 'Hmm, your passwords don\'t match. Try again?', | |
44 | - }, | |
45 | - }, | |
46 | - submitHandler() { handleReset(); }, | |
47 | - }); | |
48 | -}; | |
49 | - | |
50 | -export default function handleResetPassword(options) { | |
51 | - component = options.component; | |
52 | - token = options.token; | |
53 | - validate(); | |
54 | -} |
imports/modules/signup.js
... | ... | @@ -1,97 +0,0 @@ |
1 | -/* eslint-disable no-undef */ | |
2 | - | |
3 | -import { browserHistory } from 'react-router'; | |
4 | -import { Accounts } from 'meteor/accounts-base'; | |
5 | -import { Bert } from 'meteor/themeteorchef:bert'; | |
6 | -import { Loading } from '/imports/client/components/Loading'; | |
7 | -import './validation.js'; | |
8 | -import { Orgs } from '/imports/collections/orgs/index'; | |
9 | - | |
10 | -let component; | |
11 | - | |
12 | -const getUserData = () => ({ | |
13 | - email: document.querySelector('[name="emailAddress"]').value, | |
14 | - password: document.querySelector('[name="password"]').value, | |
15 | - profile: { | |
16 | - name: { | |
17 | - first: document.querySelector('[name="firstName"]').value, | |
18 | - last: document.querySelector('[name="lastName"]').value, | |
19 | - }, | |
20 | - }, | |
21 | -}); | |
22 | - | |
23 | -const signup = () => { | |
24 | - const user = getUserData(); | |
25 | - | |
26 | - Accounts.createUser(user, (error) => { | |
27 | - if (error) { | |
28 | - Bert.alert(error.reason, 'danger'); | |
29 | - } else { | |
30 | - browserHistory.push('/'); | |
31 | - Bert.alert('Welcome!', 'success'); | |
32 | - } | |
33 | - }); | |
34 | -}; | |
35 | -$.validator.addMethod( | |
36 | - "uniqueSlug", | |
37 | - function(value, element) { | |
38 | - slug = Orgs.find({slug:value}).fetch(); | |
39 | - console.log(slug); | |
40 | - if(slug.length>0){ | |
41 | - return false; | |
42 | - }else{ | |
43 | - return true | |
44 | - } | |
45 | - }, | |
46 | - "Name is Already Taken" | |
47 | -); | |
48 | -const validate = () => { | |
49 | - $(component.signupForm).validate({ | |
50 | - rules: { | |
51 | - orgSlug: { | |
52 | - required: true, | |
53 | - uniqueSlug: true | |
54 | - }, | |
55 | - firstName: { | |
56 | - required: true, | |
57 | - }, | |
58 | - lastName: { | |
59 | - required: true, | |
60 | - }, | |
61 | - emailAddress: { | |
62 | - required: true, | |
63 | - email: true, | |
64 | - }, | |
65 | - password: { | |
66 | - required: true, | |
67 | - minlength: 6, | |
68 | - }, | |
69 | - }, | |
70 | - messages: { | |
71 | - orgSlug: { | |
72 | - required: 'Choose your school url', | |
73 | - uniqueSlug: 'This has already been taken!' | |
74 | - }, | |
75 | - firstName: { | |
76 | - required: 'First name?', | |
77 | - }, | |
78 | - lastName: { | |
79 | - required: 'Last name?', | |
80 | - }, | |
81 | - emailAddress: { | |
82 | - required: 'Need an email address here.', | |
83 | - email: 'Is this email address legit?', | |
84 | - }, | |
85 | - password: { | |
86 | - required: 'Need a password here.', | |
87 | - minlength: 'Use at least six characters, please.', | |
88 | - }, | |
89 | - }, | |
90 | - submitHandler() { signup(); }, | |
91 | - }); | |
92 | -}; | |
93 | - | |
94 | -export default function handleSignup(options) { | |
95 | - component = options.component; | |
96 | - validate(); | |
97 | -} |
imports/modules/validation.js
imports/startup/client/routes.js
... | ... | @@ -4,17 +4,13 @@ import React from 'react'; |
4 | 4 | import { render } from 'react-dom'; |
5 | 5 | import { Router, Route, IndexRoute, browserHistory } from 'react-router'; |
6 | 6 | import { Meteor } from 'meteor/meteor'; |
7 | -import App from '../../ui/layouts/App.js'; | |
8 | -import Documents from '../../ui/pages/Documents.js'; | |
9 | -import NewDocument from '../../ui/pages/NewDocument.js'; | |
10 | -import EditDocument from '../../ui/containers/EditDocument.js'; | |
11 | -import ViewDocument from '../../ui/containers/ViewDocument.js'; | |
12 | -import Index from '../../ui/pages/Index.js'; | |
13 | -import Login from '../../ui/pages/Login.js'; | |
14 | -import NotFound from '../../ui/pages/NotFound.js'; | |
15 | -import RecoverPassword from '../../ui/pages/RecoverPassword.js'; | |
16 | -import ResetPassword from '../../ui/pages/ResetPassword.js'; | |
17 | -import Signup from '../../ui/pages/Signup.js'; | |
7 | +import App from '/imports/client/layouts/OrgApp'; | |
8 | +import Index from '/imports/client/views/app/module/Index'; | |
9 | +import Login from '/imports/client/views/org/enter/Login'; | |
10 | +import NotFound from '/imports/client/views/org/NotFound'; | |
11 | +import RecoverPassword from '/imports/client/views/org/enter/RecoverPassword'; | |
12 | +import ResetPassword from '/imports/client/views/org/enter/ResetPassword'; | |
13 | +import Signup from '/imports/client/views/nonOrg/enter/SignupView'; | |
18 | 14 | import { Orgs } from '/imports/collections/orgs/index'; |
19 | 15 | |
20 | 16 | |
... | ... | @@ -26,6 +22,8 @@ const authenticate = (nextState, replace) => { |
26 | 22 | }); |
27 | 23 | } |
28 | 24 | }; |
25 | + | |
26 | + | |
29 | 27 | const detectOrg = (nextState, replace) => { |
30 | 28 | orgSlug = ""; |
31 | 29 | var hostnameArray = document.location.hostname.split( "." ); |
... | ... | @@ -34,10 +32,9 @@ const detectOrg = (nextState, replace) => { |
34 | 32 | } |
35 | 33 | if(orgSlug!=""){ |
36 | 34 | Meteor.call('checkExistingOrg', {slug:orgSlug}, function(err, res) { |
37 | - if(res.length>0){ | |
38 | - console.log(res); | |
39 | - console.log(res[0]._id._str); | |
40 | - Session.set('orgId', res[0]._id._str); | |
35 | + console.log(res); | |
36 | + if(res){ | |
37 | + Session.set('orgId', res._id._str); | |
41 | 38 | render(getOrgRoutes(),document.getElementById('react-root')); |
42 | 39 | }else{ |
43 | 40 | render(getInvalidOrgRoute(),document.getElementById('react-root')); |
... | ... | @@ -49,9 +46,14 @@ const detectOrg = (nextState, replace) => { |
49 | 46 | } |
50 | 47 | const checkSlug = (nextState, replace) => { |
51 | 48 | orgId = Session.get('orgId'); |
52 | - console.log("orgId"); | |
53 | - console.log(orgId); | |
54 | 49 | } |
50 | + | |
51 | +/** | |
52 | +There are three types of routes | |
53 | +1)getOrgRoutes: all the routes that should be present for a registered org | |
54 | +2)getInvalidOrgRoute: all the routes where someone tries to enter a subdomain which hasn't been registered yet (404 mostly :D) | |
55 | +3)getNonOrgRoutes: all routes linked to normal site, ie signing up a new org. CHeking out demo and everything internal | |
56 | +**/ | |
55 | 57 | const getOrgRoutes = () => ( |
56 | 58 | <Router history={ browserHistory }> |
57 | 59 | <Route path="/" component={ App }> |
... | ... | @@ -63,20 +65,21 @@ const getOrgRoutes = () => ( |
63 | 65 | </Route> |
64 | 66 | </Router> |
65 | 67 | ) |
66 | -const getNonOrgRoutes = () => ( | |
68 | + | |
69 | +const getInvalidOrgRoute = () => ( | |
67 | 70 | <Router history={ browserHistory }> |
68 | 71 | <Route path="/" component={ App }> |
69 | - <IndexRoute name="index" component={ Index } onEnter={ checkSlug } /> | |
70 | - <Route name="signup" path="/signup" component={ Signup } /> | |
72 | + <IndexRoute name="index" component={ NotFound } /> | |
71 | 73 | <Route path="*" component={ NotFound } /> |
72 | 74 | </Route> |
73 | 75 | </Router> |
74 | 76 | ) |
75 | 77 | |
76 | -const getInvalidOrgRoute = () => ( | |
78 | +const getNonOrgRoutes = () => ( | |
77 | 79 | <Router history={ browserHistory }> |
78 | 80 | <Route path="/" component={ App }> |
79 | - <IndexRoute name="index" component={ NotFound } /> | |
81 | + <IndexRoute name="index" component={ Index } onEnter={ checkSlug } /> | |
82 | + <Route name="signup" path="/signup" component={ Signup } /> | |
80 | 83 | <Route path="*" component={ NotFound } /> |
81 | 84 | </Route> |
82 | 85 | </Router> | ... | ... |
imports/ui/components/AppNavigation.js
... | ... | @@ -1,27 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { Navbar } from 'react-bootstrap'; | |
3 | -import { Link } from 'react-router'; | |
4 | -import PublicNavigation from './PublicNavigation.js'; | |
5 | -import AuthenticatedNavigation from './AuthenticatedNavigation.js'; | |
6 | - | |
7 | -const renderNavigation = hasUser => (hasUser ? <AuthenticatedNavigation /> : <PublicNavigation />); | |
8 | - | |
9 | -const AppNavigation = ({ hasUser }) => ( | |
10 | - <Navbar> | |
11 | - <Navbar.Header> | |
12 | - <Navbar.Brand> | |
13 | - <Link to="/">Application Name</Link> | |
14 | - </Navbar.Brand> | |
15 | - <Navbar.Toggle /> | |
16 | - </Navbar.Header> | |
17 | - <Navbar.Collapse> | |
18 | - { renderNavigation(hasUser) } | |
19 | - </Navbar.Collapse> | |
20 | - </Navbar> | |
21 | -); | |
22 | - | |
23 | -AppNavigation.propTypes = { | |
24 | - hasUser: React.PropTypes.object, | |
25 | -}; | |
26 | - | |
27 | -export default AppNavigation; |
imports/ui/components/AuthenticatedNavigation.js
... | ... | @@ -1,30 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { browserHistory } from 'react-router'; | |
3 | -import { LinkContainer } from 'react-router-bootstrap'; | |
4 | -import { Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap'; | |
5 | -import { Meteor } from 'meteor/meteor'; | |
6 | - | |
7 | -const handleLogout = () => Meteor.logout(() => browserHistory.push('/login')); | |
8 | - | |
9 | -const userName = () => { | |
10 | - const user = Meteor.user(); | |
11 | - const name = user && user.profile ? user.profile.name : ''; | |
12 | - return user ? `${name.first} ${name.last}` : ''; | |
13 | -}; | |
14 | - | |
15 | -const AuthenticatedNavigation = () => ( | |
16 | - <div> | |
17 | - <Nav> | |
18 | - <LinkContainer to="/documents"> | |
19 | - <NavItem eventKey={ 2 } href="/documents">Documents</NavItem> | |
20 | - </LinkContainer> | |
21 | - </Nav> | |
22 | - <Nav pullRight> | |
23 | - <NavDropdown eventKey={ 3 } title={ userName() } id="basic-nav-dropdown"> | |
24 | - <MenuItem eventKey={ 3.1 } onClick={ handleLogout }>Logout</MenuItem> | |
25 | - </NavDropdown> | |
26 | - </Nav> | |
27 | - </div> | |
28 | -); | |
29 | - | |
30 | -export default AuthenticatedNavigation; |
imports/ui/components/DocumentEditor.js
... | ... | @@ -1,46 +0,0 @@ |
1 | -/* eslint-disable max-len, no-return-assign */ | |
2 | - | |
3 | -import React from 'react'; | |
4 | -import { FormGroup, ControlLabel, FormControl, Button } from 'react-bootstrap'; | |
5 | -import documentEditor from '../../modules/document-editor.js'; | |
6 | - | |
7 | -export default class DocumentEditor extends React.Component { | |
8 | - componentDidMount() { | |
9 | - documentEditor({ component: this }); | |
10 | - setTimeout(() => { document.querySelector('[name="title"]').focus(); }, 0); | |
11 | - } | |
12 | - | |
13 | - render() { | |
14 | - const { doc } = this.props; | |
15 | - return (<form | |
16 | - ref={ form => (this.documentEditorForm = form) } | |
17 | - onSubmit={ event => event.preventDefault() } | |
18 | - > | |
19 | - <FormGroup> | |
20 | - <ControlLabel>Title</ControlLabel> | |
21 | - <FormControl | |
22 | - type="text" | |
23 | - name="title" | |
24 | - defaultValue={ doc && doc.title } | |
25 | - placeholder="Oh, The Places You'll Go!" | |
26 | - /> | |
27 | - </FormGroup> | |
28 | - <FormGroup> | |
29 | - <ControlLabel>Body</ControlLabel> | |
30 | - <FormControl | |
31 | - componentClass="textarea" | |
32 | - name="body" | |
33 | - defaultValue={ doc && doc.body } | |
34 | - placeholder="Congratulations! Today is your day. You're off to Great Places! You're off and away!" | |
35 | - /> | |
36 | - </FormGroup> | |
37 | - <Button type="submit" bsStyle="success"> | |
38 | - { doc && doc._id ? 'Save Changes' : 'Add Document' } | |
39 | - </Button> | |
40 | - </form>); | |
41 | - } | |
42 | -} | |
43 | - | |
44 | -DocumentEditor.propTypes = { | |
45 | - doc: React.PropTypes.object, | |
46 | -}; |
imports/ui/components/DocumentsList.js
... | ... | @@ -1,24 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { browserHistory } from 'react-router'; | |
3 | -import { ListGroup, ListGroupItem, Alert } from 'react-bootstrap'; | |
4 | - | |
5 | -const handleNav = (_id) => { | |
6 | - browserHistory.push(`/documents/${_id}`); | |
7 | -} | |
8 | - | |
9 | -const DocumentsList = ({ documents }) => ( | |
10 | - documents.length > 0 ? <ListGroup className="DocumentsList"> | |
11 | - {documents.map(({ _id, title }) => ( | |
12 | - <ListGroupItem key={ _id } onClick={ () => handleNav(_id) }> | |
13 | - { title } | |
14 | - </ListGroupItem> | |
15 | - ))} | |
16 | - </ListGroup> : | |
17 | - <Alert bsStyle="warning">No documents yet.</Alert> | |
18 | -); | |
19 | - | |
20 | -DocumentsList.propTypes = { | |
21 | - documents: React.PropTypes.array, | |
22 | -}; | |
23 | - | |
24 | -export default DocumentsList; |
imports/ui/components/Loading.js
... | ... | @@ -1,30 +0,0 @@ |
1 | -import React from 'react'; | |
2 | - | |
3 | -const Loading = () => ( | |
4 | - <svg | |
5 | - version="1.1" | |
6 | - className="Loading" | |
7 | - xmlns="http://www.w3.org/2000/svg" | |
8 | - x="0px" | |
9 | - y="0px" | |
10 | - width="40px" | |
11 | - height="40px" | |
12 | - viewBox="0 0 40 40" | |
13 | - enableBackground="new 0 0 40 40"> | |
14 | - <path | |
15 | - opacity="1.0" | |
16 | - fill="#eee" | |
17 | - d="M20.201,5.169c-8.254,0-14.946,6.692-14.946,14.946c0,8.255,6.692,14.946, | |
18 | - 14.946,14.946s14.946-6.691,14.946-14.946C35.146,11.861,28.455,5.169,20.201, | |
19 | - 5.169z M20.201,31.749c-6.425,0-11.634-5.208-11.634-11.634c0-6.425, | |
20 | - 5.209-11.634,11.634-11.634c6.425,0,11.633,5.209,11.633,11.634C31.834, | |
21 | - 26.541,26.626,31.749,20.201,31.749z"/> | |
22 | - <path | |
23 | - fill="#da5347" | |
24 | - d="M26.013,10.047l1.654-2.866c-2.198-1.272-4.743-2.012-7.466-2.012h0v3.312h0 | |
25 | - C22.32,8.481,24.301,9.057,26.013,10.047z"> | |
26 | - </path> | |
27 | - </svg> | |
28 | -); | |
29 | - | |
30 | -export default Loading; |
imports/ui/components/PublicNavigation.js
... | ... | @@ -1,16 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { LinkContainer } from 'react-router-bootstrap'; | |
3 | -import { Nav, NavItem } from 'react-bootstrap'; | |
4 | - | |
5 | -const PublicNavigation = () => ( | |
6 | - <Nav pullRight> | |
7 | - <LinkContainer to="signup"> | |
8 | - <NavItem eventKey={ 1 } href="/signup">Sign Up</NavItem> | |
9 | - </LinkContainer> | |
10 | - <LinkContainer to="login"> | |
11 | - <NavItem eventKey={ 2 } href="/login">Log In</NavItem> | |
12 | - </LinkContainer> | |
13 | - </Nav> | |
14 | -); | |
15 | - | |
16 | -export default PublicNavigation; |
imports/ui/containers/AppNavigation.js
... | ... | @@ -1,7 +0,0 @@ |
1 | -import { composeWithTracker } from 'react-komposer'; | |
2 | -import { Meteor } from 'meteor/meteor'; | |
3 | -import AppNavigation from '../components/AppNavigation.js'; | |
4 | - | |
5 | -const composer = (props, onData) => onData(null, { hasUser: Meteor.user() }); | |
6 | - | |
7 | -export default composeWithTracker(composer, {}, {}, { pure: false })(AppNavigation); |
imports/ui/containers/DocumentsList.js
... | ... | @@ -1,15 +0,0 @@ |
1 | -import { composeWithTracker } from 'react-komposer'; | |
2 | -import { Meteor } from 'meteor/meteor'; | |
3 | -import Documents from '../../api/documents/documents.js'; | |
4 | -import DocumentsList from '../components/DocumentsList.js'; | |
5 | -import Loading from '../components/Loading.js'; | |
6 | - | |
7 | -const composer = (params, onData) => { | |
8 | - const subscription = Meteor.subscribe('documents.list'); | |
9 | - if (subscription.ready()) { | |
10 | - const documents = Documents.find().fetch(); | |
11 | - onData(null, { documents }); | |
12 | - } | |
13 | -}; | |
14 | - | |
15 | -export default composeWithTracker(composer, Loading)(DocumentsList); |
imports/ui/containers/EditDocument.js
... | ... | @@ -1,16 +0,0 @@ |
1 | -import { Meteor } from 'meteor/meteor'; | |
2 | -import { composeWithTracker } from 'react-komposer'; | |
3 | -import Documents from '../../api/documents/documents.js'; | |
4 | -import EditDocument from '../pages/EditDocument.js'; | |
5 | -import Loading from '../components/Loading.js'; | |
6 | - | |
7 | -const composer = ({ params }, onData) => { | |
8 | - const subscription = Meteor.subscribe('documents.view', params._id); | |
9 | - | |
10 | - if (subscription.ready()) { | |
11 | - const doc = Documents.findOne(); | |
12 | - onData(null, { doc }); | |
13 | - } | |
14 | -}; | |
15 | - | |
16 | -export default composeWithTracker(composer, Loading)(EditDocument); |
imports/ui/containers/ViewDocument.js
... | ... | @@ -1,16 +0,0 @@ |
1 | -import { Meteor } from 'meteor/meteor'; | |
2 | -import { composeWithTracker } from 'react-komposer'; | |
3 | -import Documents from '../../api/documents/documents.js'; | |
4 | -import ViewDocument from '../pages/ViewDocument.js'; | |
5 | -import Loading from '../components/Loading.js'; | |
6 | - | |
7 | -const composer = ({ params }, onData) => { | |
8 | - const subscription = Meteor.subscribe('documents.view', params._id); | |
9 | - | |
10 | - if (subscription.ready()) { | |
11 | - const doc = Documents.findOne(); | |
12 | - onData(null, { doc }); | |
13 | - } | |
14 | -}; | |
15 | - | |
16 | -export default composeWithTracker(composer, Loading)(ViewDocument); |
imports/ui/layouts/App.js
... | ... | @@ -1,18 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { Grid } from 'react-bootstrap'; | |
3 | -import AppNavigation from '../containers/AppNavigation.js'; | |
4 | - | |
5 | -const App = ({ children }) => ( | |
6 | - <div> | |
7 | - <AppNavigation /> | |
8 | - <Grid> | |
9 | - { children } | |
10 | - </Grid> | |
11 | - </div> | |
12 | -); | |
13 | - | |
14 | -App.propTypes = { | |
15 | - children: React.PropTypes.node, | |
16 | -}; | |
17 | - | |
18 | -export default App; |
imports/ui/pages/Index.js
... | ... | @@ -1,15 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { Jumbotron } from 'react-bootstrap'; | |
3 | - | |
4 | -const Index = () => ( | |
5 | - <div className="Index"> | |
6 | - <Jumbotron className="text-center"> | |
7 | - <h2>Base</h2> | |
8 | - <p>A starting point for Meteor applications.</p> | |
9 | - <p><a className="btn btn-success" href="https://themeteorchef.com/base" role="button">Read the Documentation</a></p> | |
10 | - <p style={ { fontSize: '16px', color: '#aaa' } }>Currently at v4.11.1</p> | |
11 | - </Jumbotron> | |
12 | - </div> | |
13 | -); | |
14 | - | |
15 | -export default Index; |
imports/ui/pages/NotFound.js
... | ... | @@ -1,12 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { Alert } from 'react-bootstrap'; | |
3 | - | |
4 | -const NotFound = () => ( | |
5 | - <div className="NotFound"> | |
6 | - <Alert bsStyle="danger"> | |
7 | - <p><strong>Error [404]</strong>: { window.location.pathname } does not exist.</p> | |
8 | - </Alert> | |
9 | - </div> | |
10 | -); | |
11 | - | |
12 | -export default NotFound; |
imports/ui/pages/Signup.js
... | ... | @@ -1,116 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { Link } from 'react-router'; | |
3 | -import { Row, Col, FormGroup, | |
4 | - ControlLabel, FormControl, | |
5 | - InputGroup, Button } from 'react-bootstrap'; | |
6 | -import handleSignup from '../../modules/signup'; | |
7 | -import { Orgs } from '/imports/collections/orgs/index'; | |
8 | - | |
9 | -export default class Signup extends React.Component { | |
10 | - constructor(props) { | |
11 | - super(props); | |
12 | - this.state = { | |
13 | - orgSlug: "" | |
14 | - }; | |
15 | - } | |
16 | - componentWillMount(){ | |
17 | - Meteor.subscribe('allOrgsSlug'); | |
18 | - } | |
19 | - | |
20 | - componentDidMount() { | |
21 | - handleSignup({ component: this }); | |
22 | - } | |
23 | - handleChange(e) { | |
24 | - this.setState({ orgSlug: e.target.value }); | |
25 | - } | |
26 | - handleSubmit(event) { | |
27 | - event.preventDefault(); | |
28 | - } | |
29 | - checkExistingOrgSlug() { | |
30 | - console.log(this.state.orgSlug); | |
31 | - if(this.state.orgSlug==""){return null} | |
32 | - searchOrg = Orgs.find({slug:this.state.orgSlug}).fetch(); | |
33 | - if(searchOrg.length>0){ | |
34 | - return "error" | |
35 | - }else{ | |
36 | - return "success" | |
37 | - } | |
38 | - } | |
39 | - render() { | |
40 | - return ( | |
41 | - <div className="Signup"> | |
42 | - <Row> | |
43 | - <Col xs={ 12 } sm={ 6 } md={ 4 }> | |
44 | - <h4 className="page-header">Sign Up</h4> | |
45 | - <form | |
46 | - ref={ form => (this.signupForm = form) } | |
47 | - onSubmit={ this.handleSubmit } | |
48 | - > | |
49 | - <Row> | |
50 | - <Col xs={ 12 } sm={ 12 }> | |
51 | - <FormGroup controlId="orgSlugField" validationState={this.checkExistingOrgSlug()}> | |
52 | - <ControlLabel>Organisation name</ControlLabel> | |
53 | - <InputGroup> | |
54 | - <FormControl | |
55 | - type ="text" | |
56 | - ref ="orgSlug" | |
57 | - name ="orgSlug" | |
58 | - placeholder ="School Name" | |
59 | - onChange = {(e) => this.handleChange(e)} | |
60 | - /> | |
61 | - <InputGroup.Addon>@yd.com</InputGroup.Addon> | |
62 | - </InputGroup> | |
63 | - </FormGroup> | |
64 | - </Col> | |
65 | - </Row> | |
66 | - <Row> | |
67 | - <Col xs={ 6 } sm={ 6 }> | |
68 | - <FormGroup> | |
69 | - <ControlLabel>First Name</ControlLabel> | |
70 | - <FormControl | |
71 | - type="text" | |
72 | - ref="firstName" | |
73 | - name="firstName" | |
74 | - placeholder="First Name" | |
75 | - /> | |
76 | - </FormGroup> | |
77 | - </Col> | |
78 | - <Col xs={ 6 } sm={ 6 }> | |
79 | - <FormGroup> | |
80 | - <ControlLabel>Last Name</ControlLabel> | |
81 | - <FormControl | |
82 | - type="text" | |
83 | - ref="lastName" | |
84 | - name="lastName" | |
85 | - placeholder="Last Name" | |
86 | - /> | |
87 | - </FormGroup> | |
88 | - </Col> | |
89 | - </Row> | |
90 | - <FormGroup> | |
91 | - <ControlLabel>Email Address</ControlLabel> | |
92 | - <FormControl | |
93 | - type="text" | |
94 | - ref="emailAddress" | |
95 | - name="emailAddress" | |
96 | - placeholder="Email Address" | |
97 | - /> | |
98 | - </FormGroup> | |
99 | - <FormGroup> | |
100 | - <ControlLabel>Password</ControlLabel> | |
101 | - <FormControl | |
102 | - type="password" | |
103 | - ref="password" | |
104 | - name="password" | |
105 | - placeholder="Password" | |
106 | - /> | |
107 | - </FormGroup> | |
108 | - <Button type="submit" bsStyle="success">Sign Up</Button> | |
109 | - </form> | |
110 | - <p>Already have an account? <Link to="/login">Log In</Link>.</p> | |
111 | - </Col> | |
112 | - </Row> | |
113 | - </div> | |
114 | - ); | |
115 | - } | |
116 | -} |