Commit 878ca8a152800bbb889f6aa5a106a87f8867cf95

Authored by Deepak
1 parent a8c5a7fb6d
Exists in master

added signup form on index route for main site

imports/client/app/routes.js
1 /* eslint-disable max-len */ 1 /* eslint-disable max-len */
2 2
3 import React from 'react'; 3 import React from 'react';
4 import { render } from 'react-dom'; 4 import { render } from 'react-dom';
5 import { Router, Route, 5 import { Router, Route,
6 IndexRoute, browserHistory } from 'react-router'; 6 IndexRoute, browserHistory } from 'react-router';
7 import { Meteor } from 'meteor/meteor'; 7 import { Meteor } from 'meteor/meteor';
8 8
9 /** 9 /**
10 * General Components 10 * General Components
11 */ 11 */
12 import Index from '/imports/client/views/app/module/Index'; 12 import Index from '/imports/client/views/app/module/Index';
13 import NotFound from '/imports/client/views/org/NotFound'; 13 import NotFound from '/imports/client/views/org/NotFound';
14 14
15 /** 15 /**
16 * Org Components 16 * Org Components
17 */ 17 */
18 18
19 import { App } from '/imports/client/layouts/OrgApp'; 19 import { App } from '/imports/client/layouts/OrgApp';
20 import { AppModule } from '/imports/client/views/org/app/module/Index'; 20 import { AppModule } from '/imports/client/views/org/app/module/Index';
21 import { Orgs } from '/imports/collections/orgs/index'; 21 import { Orgs } from '/imports/collections/orgs/index';
22 import { importCsvController } from '/imports/client/views/org/importCsv/index' 22 import { importCsvController } from '/imports/client/views/org/importCsv/index'
23 23
24 //admin 24 //admin
25 import { StudentDataController } from '/imports/client/views/org/admin/students/index' 25 import { StudentDataController } from '/imports/client/views/org/admin/students/index'
26 import { teachersViewController } from '/imports/client/views/org/admin/teachers/index' 26 import { teachersViewController } from '/imports/client/views/org/admin/teachers/index'
27 //students 27 //students
28 28
29 //teachers 29 //teachers
30 30
31 //parents 31 //parents
32 32
33 33
34 34
35 /** 35 /**
36 * NonOrg Components 36 * NonOrg Components
37 */ 37 */
38 import Signup from '/imports/client/views/nonOrg/enter/SignupView'; 38 import Signup from '/imports/client/views/nonOrg/enter/SignupView';
39 import { NonOrgApp } from '/imports/client/layouts/NonOrgApp'; 39 import { NonOrgApp } from '/imports/client/layouts/NonOrgApp';
40 import {NonOrgAppModule} from '/imports/client/views/nonOrg/app/module/Index';
40 41
41 /** 42 /**
42 * Invalid Org Components 43 * Invalid Org Components
43 */ 44 */
44 45
45 /** 46 /**
46 There are three types of routes 47 There are three types of routes
47 1)getOrgRoutes: all the routes that should be present for a registered org 48 1)getOrgRoutes: all the routes that should be present for a registered org
48 2)getInvalidOrgRoute: all the routes where someone tries to enter a subdomain which hasn't been registered yet (404 mostly :D) 49 2)getInvalidOrgRoute: all the routes where someone tries to enter a subdomain which hasn't been registered yet (404 mostly :D)
49 3)getNonOrgRoutes: all routes linked to normal site, ie signing up a new org. CHeking out demo and everything internal 50 3)getNonOrgRoutes: all routes linked to normal site, ie signing up a new org. CHeking out demo and everything internal
50 **/ 51 **/
51 const getOrgRoutes = () => ( 52 const getOrgRoutes = () => (
52 <Router history={ browserHistory }> 53 <Router history={ browserHistory }>
53 <Route path="/" component={ App }> 54 <Route path="/" component={ App }>
54 <IndexRoute name="index" component={ AppModule } /> 55 <IndexRoute name="index" component={ AppModule } />
55 <Route name="import" path="/import" component={ importCsvController } /> 56 <Route name="import" path="/import" component={ importCsvController } />
56 <Route name="student" path="/students" component={ StudentDataController } /> 57 <Route name="student" path="/students" component={ StudentDataController } />
57 <Route name="teachers" path="/teachers" component={ teachersViewController } /> 58 <Route name="teachers" path="/teachers" component={ teachersViewController } />
58 <Route path="*" component={ NotFound } /> 59 <Route path="*" component={ NotFound } />
59 </Route> 60 </Route>
60 </Router> 61 </Router>
61 ) 62 )
62 63
63 64
64 const getInvalidOrgRoute = () => ( 65 const getInvalidOrgRoute = () => (
65 <Router history={ browserHistory }> 66 <Router history={ browserHistory }>
66 <Route path="/" component={ App }> 67 <Route path="/" component={ App }>
67 <IndexRoute name="index" component={ NotFound } /> 68 <IndexRoute name="index" component={ NotFound } />
68 <Route path="*" component={ NotFound } /> 69 <Route path="*" component={ NotFound } />
69 </Route> 70 </Route>
70 </Router> 71 </Router>
71 ) 72 )
72 73
73 const getNonOrgRoutes = () => ( 74 const getNonOrgRoutes = () => (
74 <Router history={ browserHistory }> 75 <Router history={ browserHistory }>
75 <Route path="/" component={ NonOrgApp }> 76 <Route path="/" component={ NonOrgApp }>
76 <IndexRoute name="index" component={ Index } /> 77 <IndexRoute name="index" component={ NonOrgAppModule } />
77 <Route name="signup" path="/signup" component={ Signup } /> 78 <Route name="signup" path="/signup" component={ Signup } />
78 <Route path="*" component={ NotFound } /> 79 <Route path="*" component={ NotFound } />
79 </Route> 80 </Route>
80 </Router> 81 </Router>
81 ) 82 )
82 83
83 //Authenticate function to give access to users only 84 //Authenticate function to give access to users only
84 const authenticate = (nextState, replace) => { 85 const authenticate = (nextState, replace) => {
85 if (!Meteor.loggingIn() && !Meteor.userId()) { 86 if (!Meteor.loggingIn() && !Meteor.userId()) {
86 replace({ 87 replace({
87 pathname: '/login', 88 pathname: '/login',
88 state: { nextPathname: nextState.location.pathname }, 89 state: { nextPathname: nextState.location.pathname },
89 }); 90 });
90 } 91 }
91 }; 92 };
92 93
93 94
94 /** 95 /**
95 96
96 **/ 97 **/
97 const detectOrg = () => { 98 const detectOrg = () => {
98 orgSlug = ""; 99 orgSlug = "";
99 var hostnameArray = document.location.hostname.split( "." ); 100 var hostnameArray = document.location.hostname.split( "." );
100 if(hostnameArray[1]=='localhost'){ 101 if(hostnameArray[1]=='localhost'){
101 orgSlug = hostnameArray[0]; 102 orgSlug = hostnameArray[0];
102 } 103 }
103 if(orgSlug!=""){ 104 if(orgSlug!=""){
104 Meteor.call('checkExistingOrg', {slug:orgSlug}, function(err, res) { 105 Meteor.call('checkExistingOrg', {slug:orgSlug}, function(err, res) {
105 if(res){ 106 if(res){
106 Session.set('orgId', res._id); 107 Session.set('orgId', res._id);
107 Session.set('orgSlug', orgSlug); 108 Session.set('orgSlug', orgSlug);
108 render(getOrgRoutes(),document.getElementById('app')); 109 render(getOrgRoutes(),document.getElementById('app'));
109 }else{ 110 }else{
110 render(getInvalidOrgRoute(),document.getElementById('app')); 111 render(getInvalidOrgRoute(),document.getElementById('app'));
111 } 112 }
112 }); 113 });
113 }else{ 114 }else{
114 render(getNonOrgRoutes(),document.getElementById('app')); 115 render(getNonOrgRoutes(),document.getElementById('app'));
115 } 116 }
116 } 117 }
117 const checkSlug = (nextState, replace) => { 118 const checkSlug = (nextState, replace) => {
118 orgId = Session.get('orgId'); 119 orgId = Session.get('orgId');
119 } 120 }
120 121
121 122
122 Meteor.startup(() => { 123 Meteor.startup(() => {
123 detectOrg(); 124 detectOrg();
124 }); 125 });
125 126
imports/client/layouts/NonOrgApp.js
1 import React, { Component } from 'react'; 1 import React, { Component } from 'react';
2 import { Grid } from 'react-bootstrap'; 2 import { Grid } from 'react-bootstrap';
3 import {AppNavigationController} from '/imports/client/views/nonOrg/app/module/navigation/index';
4 /** 3 /**
5 * user based redirection will take place here 4 * user based redirection will take place here
6 */ 5 */
7 export class App extends Component { 6 export class NonOrgApp extends Component {
8 constructor(props) { 7 constructor(props) {
9 super(props); 8 super(props);
10 this.state = { 9 this.state = {
11 10
12 }; 11 };
13 }; 12 };
14 render(){ 13 render(){
15 return ( 14 return (
16 <div> 15 <div>
17 <AppNavigationController />
18 <Grid> 16 <Grid>
19 { this.props.children } 17 { this.props.children }
20 </Grid> 18 </Grid>
21 </div> 19 </div>
22 ) 20 )
23 } 21 }
24 } 22 }
25 23
imports/client/views/nonOrg/app/module/AppLayout.js
File was created 1 import _ from 'lodash';
2 import { Meteor } from 'meteor/meteor';
3 import React, { Component } from 'react';
4 import { Link } from 'react-router';
5 import { Avatar } from '/imports/client/components/Avatar';
6 import { Icon } from '/imports/client/components/Icon';
7 import classNames from 'classnames';
8
9 import { logout } from '/imports/client/app/utils/loginMethods';
10
11 import Signup from '/imports/client/views/nonOrg/enter/SignupView';
12 import { VerifyModule } from '/imports/client/views/verify/module/index';
13 import ReactSVG from 'react-svg'
14
15 export class AppLayout extends Component {
16 render() {
17 const {user, org} = this.props.data;
18 console.log(user);
19 if(!user) {
20 return (
21 <Signup
22 />
23 );
24 }
25
26 if(!user.isEmailVerified()) {
27 return (
28 <VerifyModule
29 pane = {this.props.location.query.verify}
30 location = {this.props.location}
31 />
32 );
33 }
34
35
36 return (
37 <div className = "appLayout-box">
38 <div className = "appLayout-wrapOuter">
39 <div className = "appLayout-wrapInner">
40 <div className = "appLayout-menuWrap">
41 </div>
42 <div className = "appLayout-contentWrap">
43 <div className = "appLayout-content">
44
45 </div>
46 </div>
47 </div>
48 </div>
49 </div>
50 );
51 };
52
53 };
54
imports/client/views/nonOrg/app/module/Index.js
1 import React from 'react'; 1 // import { AppModule } from '/imports/client/views/app/module/index'
2 import { Jumbotron } from 'react-bootstrap'; 2 import {
3 3 composeWithTracker,
4 const Index = () => ( 4 compose,
5 <div className="Index"> 5 composeAll
6 <Jumbotron className="text-center"> 6 } from 'react-komposer';
7 <h2>Base</h2> 7 import { AppLayout } from './AppLayout';
8 <p>A starting point for Meteor applications.</p> 8 import { Loading } from '/imports/client/components/Loading';
9 <p><a className="btn btn-success" href="https://themeteorchef.com/base" role="button">Read the Documentation</a></p> 9
10 <p style={ { fontSize: '16px', color: '#aaa' } }>Currently at v4.11.1</p> 10 import { Users } from '/imports/collections/users/index';
11 </Jumbotron> 11 import { Orgs } from '/imports/collections/orgs/index';
12 </div> 12
13 ); 13
14 14 const meteorTick = (props, onData) => {
15 export default Index; 15
16 const handles = [
17 Meteor.subscribe('users.current'),
18 Meteor.subscribe('orgs.current'),
19 ];
20
21 if(_.every(handles, (handle) => (handle.ready()) )) {
22 const user = Users.current();
23 console.log(user);
24 onData(null, {
25 data: {
26 user: user,
27 org: Orgs.current(),
28 },
29 });
30 }
31
32 return () => {
33 _.each(handles, (handle) => handle.stop() );
34 };
35 };
36
37
38 const reduxTick = (props, onData) => {
39 onData(null, {
40 location: props.location,
41 data: {}
42 });
43 };
44
45
46 export const NonOrgAppModule = composeAll(
47 composeWithTracker(meteorTick, Loading),
48 compose(reduxTick, Loading),
49 )(AppLayout);
16 50
imports/client/views/nonOrg/app/module/navigation/AppNavigation.js
1 import React, { Component } from 'react'; 1 import React, { Component } from 'react';
2 import { Navbar } from 'react-bootstrap'; 2 import { Navbar } from 'react-bootstrap';
3 import { Link } from 'react-router'; 3 import { Link } from 'react-router';
4 import {PublicNavigation} from './PublicNavigation.js'; 4 import {PublicNavigation} from './PublicNavigation.js';
5 import {AuthenticatedNavigation} from './AuthenticatedNavigation.js'; 5 import {AuthenticatedNavigation} from './AuthenticatedNavigation.js';
6 // import '/imports/client/assets/css/icons/icomoon/styles.css'; 6 // import '/imports/client/assets/css/icons/icomoon/styles.css';
7 // import '/imports/client/assets/css/bootstrap.css'; 7 // import '/imports/client/assets/css/bootstrap.css';
8 // import '/imports/client/assets/css/core.css'; 8 // import '/imports/client/assets/css/core.css';
9 // import '/imports/client/assets/css/components.css'; 9 // import '/imports/client/assets/css/components.css';
10 // import '/imports/client/assets/css/colors.css'; 10 // import '/imports/client/assets/css/colors.css';
11 // import '/imports/client/assets/css/colors.css'; 11 // import '/imports/client/assets/css/colors.css';
12 export class AppNavigation extends Component { 12 export class AppNavigation extends Component {
13 13
14 constructor(props) { 14 constructor(props) {
15 super(props); 15 super(props);
16 this.state = { 16 this.state = {
17 17
18 }; 18 };
19 }; 19 };
20 20
21 onUpdate(key, value) { 21 onUpdate(key, value) {
22 this.setState({[key]: value}); 22 this.setState({[key]: value});
23 }; 23 };
24 render() { 24 render() {
25 const {user} = this.props.data; 25 const {user} = this.props.data;
26 console.log(user);
26 if(user){ 27 if(user){
27 return( 28 return(
28 <AuthenticatedNavigation 29 <AuthenticatedNavigation
29 data = {this.props.data} 30 data = {this.props.data}
30 /> 31 />
31 ) 32 )
32 }else{ 33 }else{
33 return( 34 return(
34 <Navbar> 35 <Navbar>
35 <Navbar.Header> 36 <Navbar.Header>
36 <Navbar.Brand> 37 <Navbar.Brand>
37 <Link to="/">Application Name</Link> 38 <Link to="/">Application Name</Link>
38 </Navbar.Brand> 39 </Navbar.Brand>
39 <Navbar.Toggle /> 40 <Navbar.Toggle />
40 </Navbar.Header> 41 </Navbar.Header>
41 <Navbar.Collapse> 42 <Navbar.Collapse>
42 <PublicNavigation /> 43 <PublicNavigation />
43 </Navbar.Collapse> 44 </Navbar.Collapse>
44 </Navbar> 45 </Navbar>
45 46
46 ) 47 )
47 } 48 }
48 49
49 return ( 50 return (
50 <div></div> 51 <div></div>
51 ); 52 );
52 }; 53 };
53 54
54 }; 55 };
55 56
imports/client/views/nonOrg/app/module/navigation/AuthenticatedNavigation.js
1 import React from 'react'; 1 import React from 'react';
2 import { browserHistory } from 'react-router'; 2 import { browserHistory } from 'react-router';
3 import { LinkContainer } from 'react-router-bootstrap'; 3 import { LinkContainer } from 'react-router-bootstrap';
4 import { Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap'; 4 import { Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
5 import { Meteor } from 'meteor/meteor'; 5 import { Meteor } from 'meteor/meteor';
6 6
7 const handleLogout = () => Meteor.logout(() => browserHistory.push('/login')); 7 const handleLogout = () => Meteor.logout(() => browserHistory.push('/login'));
8 8
9 const userName = () => { 9 const userName = () => {
10 const user = Meteor.user(); 10 const user = Meteor.user();
11 const name = user && user.profile ? user.profile.name : ''; 11 const name = user && user.profile ? user.profile.name : '';
12 return user ? `${name.first} ${name.last}` : ''; 12 return user ? `${name.first} ${name.last}` : '';
13 }; 13 };
14 14
15 const AuthenticatedNavigation = () => ( 15 const AuthenticatedNavigation = () => (
16 <div> 16 <div>
17 <Nav> 17 <Nav>
18 <LinkContainer to="/documents"> 18 <LinkContainer to="/documents">
19 <NavItem eventKey={ 2 } href="/documents">Documents</NavItem> 19 <NavItem eventKey={ 2 } href="/documents">Documents</NavItem>
20 </LinkContainer> 20 </LinkContainer>
21 </Nav> 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> 22 </div>
28 ); 23 );
29 24
30 export default AuthenticatedNavigation; 25 export default AuthenticatedNavigation;
31 26
imports/client/views/nonOrg/app/module/navigation/index.js
1 // import { AppNavigation } from '/imports/client/views/nonOrg/app/module/navigation/index' 1 // import { AppNavigation } from '/imports/client/views/nonOrg/app/module/navigation/index'
2 import _ from 'lodash'; 2 import _ from 'lodash';
3 import { 3 import {
4 composeWithTracker, 4 composeWithTracker,
5 compose, 5 compose,
6 composeAll 6 composeAll
7 } from 'react-komposer'; 7 } from 'react-komposer';
8 import { Loading } from '/imports/client/components/Loading'; 8 import { Loading } from '/imports/client/components/Loading';
9 9
10 import { Orgs } from '/imports/collections/orgs/index'; 10 import { Orgs } from '/imports/collections/orgs/index';
11 import { Users } from '/imports/collections/users/index'; 11 import { Users } from '/imports/collections/users/index';
12 12
13 import { AppNavigation } from './AppNavigation'; 13 import { AppNavigation } from './AppNavigation';
14 14
15 const meteorTick = (props, onData) => { 15 const meteorTick = (props, onData) => {
16 16
17 const handles = [ 17 const handles = [
18 Meteor.subscribe('users.current'), 18 Meteor.subscribe('users.current'),
19 Meteor.subscribe('orgs.current') 19 Meteor.subscribe('orgs.current')
20 ]; 20 ];
21 21
22 if(_.every(handles, (handle) => (handle.ready()) )) { 22 if(_.every(handles, (handle) => (handle.ready()) )) {
23 const user = Users.current(); 23 const user = Users.current();
24 const org = Orgs.current(); 24 const org = Orgs.current();
25 console.log(user);
25 onData(null, { 26 onData(null, {
26 data: { 27 data: {
27 user: user, 28 user: user,
28 org: org 29 org: org
29 }, 30 },
30 }); 31 });
31 } 32 }
32 33
33 return () => { 34 return () => {
34 _.each(handles, (handle) => handle.stop() ); 35 _.each(handles, (handle) => handle.stop() );
35 }; 36 };
36 }; 37 };
37 38
38 39
39 const reduxTick = (props, onData) => { 40 const reduxTick = (props, onData) => {
40 onData(null, { 41 onData(null, {
41 data: {} 42 data: {}
42 }); 43 });
43 }; 44 };
44 45
45 46
46 export const AppNavigationController = composeAll( 47 export const AppNavigationController = composeAll(
47 composeWithTracker(meteorTick, Loading), 48 composeWithTracker(meteorTick, Loading),
48 compose(reduxTick, Loading), 49 compose(reduxTick, Loading),
49 )(AppNavigation); 50 )(AppNavigation);
50 51
imports/client/views/verify/EmailPane.js
File was created 1 import React from 'react';
2 import { Link } from 'react-router';
3 import { If, Case } from '/imports/client/components/Logic';
4 import { Bert } from 'meteor/themeteorchef:bert';
5
6 import { Row, Col, Alert,ControlLabel,
7 FormGroup, FormControl, Button } from 'react-bootstrap';
8
9
10 export class EmailPane extends React.Component {
11
12 constructor(props) {
13 super(props);
14
15 this.state = {
16 email: props.user.emails[0].address,
17 form: false,
18 };
19 };
20
21 onUpdate(key, val) {
22 this.setState({[key]: val});
23 };
24
25 onSetEmail() {
26 startEmailVerification.call({email: this.state.email}, (err, res)=>{
27 Bert.alert('New verification email sent!', 'success');
28
29 });
30 this.setState({form: false});
31 };
32
33 onShowForm() {
34 this.setState({form: true});
35 };
36
37 renderForm() {
38 const {user} = this.props;
39
40 return (
41 <div className = "wizardPane-box">
42 <div className = "wizardPane-section">
43 <div className="icon-circle icon-lg">
44 <i className="icon icon-simple icon-envelope"></i>
45 </div>
46 <div className = "wizardPane-title">
47 Set your email address
48 </div>
49 <div className = "col-xs-8 horizontalform verifyEmail wizardPane-text">
50 <div className="form-row">
51 <Col sm={4}>
52 Enter email
53 </Col>
54 <Col sm={8}>
55 <input
56 type = "text"
57 value = {this.state.email}
58 onChange = {(evt) => this.onUpdate('email', evt.currentTarget.value)}
59 placeholder = "Email"
60 />
61 </Col>
62 </div>
63
64 </div>
65 </div>
66 <div className = "wizardPane-section wizardPane-footer">
67 <div
68 className = "wizardPane-button btn btn-blue"
69 onClick = {() => this.onSetEmail()}
70 >
71 Send verification email
72 </div>
73 </div>
74 </div>
75 );
76 };
77
78 renderMessage() {
79 const {user} = this.props;
80
81 return (
82 <div className = "wizardPane-box">
83 <div className = "wizardPane-section">
84
85 <div className = "wizardPane-title">
86 <i className="icon-envelope icon"></i>
87 <h3>Verify your email</h3>
88 </div>
89 <div className = "wizardPane-text">
90 Check your email โ€“ย we sent a verification link to<br/>
91 {user.emails[0].address}
92 </div>
93 </div>
94 <div className = "wizardPane-section wizardPane-footer">
95 <div className="btn"
96 className = "wizardPane-link"
97 onClick = {() => this.onShowForm()}
98 >
99 Email did not arrive or want to use a different email?
100 </div>
101 </div>
102 </div>
103 );
104 };
105
106 render() {
107 return this.state.form ? this.renderForm() : this.renderMessage();
108 };
109
110 };
111
imports/client/views/verify/module/VerifyLayout.js
File was created 1 import _ from 'lodash';
2 import { Meteor } from 'meteor/meteor';
3
4 import React, { Component } from 'react';
5 import { Link } from 'react-router';
6 import { If, Case } from '/imports/client/components/Logic';
7 import { Avatar } from '/imports/client/components/Avatar';
8
9 import { logout } from '/imports/client/app/utils/loginMethods';
10
11 import { EmailPane } from '/imports/client/views/verify/EmailPane';
12 import ReactSVG from 'react-svg'
13
14
15 export class VerifyLayout extends Component {
16
17 render() {
18 const user = this.props.data.user;
19
20 return (
21 <div className = "wizardLayout-box">
22 <div className = "wizardLayout-top">
23 <div className="container">
24 <div className = "wizardLayout-topSpace logo-space-0">
25 <ReactSVG
26 path="/files/images/svg/logo--white.svg"
27 className="enterPane__logo"
28 />
29 </div>
30 <div className = "wizardLayout-topGroup">
31 <div className = "wizardLayout-topItem">
32 <Avatar
33 user = {user}
34 size = {20}
35 small = {true}
36 />
37 &nbsp;
38 {user.getFullName()}
39 </div>
40 <div
41 className = "wizardLayout-topItem"
42 onClick = {() => logout()}
43 >
44 <i className="icon icon-simple icon-power"></i>
45 </div>
46 </div>
47 </div>
48 </div>
49
50 <div className = "wizardLayout-wrap">
51 <div className = "wizardLayout-content">
52
53 <EmailPane
54 user = {user}
55 />
56
57 </div>
58 </div>
59 </div>
60 );
61 };
62
63 };
64
65
66
imports/client/views/verify/module/index.js
File was created 1 // import { VerifyModule } from '/imports/client/views/verify/module/index'
2 import {
3 composeWithTracker,
4 compose,
5 composeAll
6 } from 'react-komposer';
7 import { VerifyLayout } from './VerifyLayout';
8 import { Loading } from '/imports/client/components/Loading';
9
10 import { Users } from '/imports/collections/users/index';
11
12
13 const meteorTick = (props, onData) => {
14
15 const handles = [
16 Meteor.subscribe('users.current'),
17 ];
18
19 if(_.every(handles, (handle) => (handle.ready()) )) {
20 const user = Users.current();
21 onData(null, {
22 data: {
23 user: user,
24 },
25 });
26 }
27
28 return () => {
29 _.each(handles, (handle) => handle.stop() );
30 };
31 };
32
33
34 const reduxTick = (props, onData) => {
35 onData(null, {
36 data: {}
37 });
38 };
39
40
41 export const VerifyModule = composeAll(
42 composeWithTracker(meteorTick, Loading),
43 compose(reduxTick, Loading),
44 )(VerifyLayout);
45
46
47
48
49
50
51
imports/server/accounts/creation.js
1 import _ from 'lodash'; 1 import _ from 'lodash';
2 import { Accounts } from 'meteor/accounts-base'; 2 import { Accounts } from 'meteor/accounts-base';
3 import { SimpleSchema } from 'meteor/aldeed:simple-schema'; 3 import { SimpleSchema } from 'meteor/aldeed:simple-schema';
4 import { ValidatedMethod } from 'meteor/mdg:validated-method'; 4 import { ValidatedMethod } from 'meteor/mdg:validated-method';
5 5
6 import { Orgs } from '/imports/collections/orgs/index'; 6 import { Orgs } from '/imports/collections/orgs/index';
7 import { Users } from '/imports/collections/users/index'; 7 import { Users } from '/imports/collections/users/index';
8 8
9 9
10 Accounts.validateNewUser((user) => { 10 Accounts.validateNewUser((user) => {
11 return !!user; 11 return !!user;
12 }); 12 });
13 13
14 Accounts.onCreateUser((options, user) => { 14 Accounts.onCreateUser((options, user) => {
15
15 if(options.orgSlug){ 16 if(options.orgSlug){
16 orgId = Orgs.insert({ 17 orgId = Orgs.insert({
17 slug: options.orgSlug, 18 slug: options.orgSlug,
18 name: options.orgName, 19 name: options.orgName,
19 setup: 1, 20 setup: 1,
20 users: [{ 21 users: [{
21 userId: user._id, 22 userId: user._id,
22 role: Users.roles.ADMIN, 23 role: Users.roles.ADMIN,
23 }], 24 }],
24 }); 25 });
25 } 26 }
27 console.log("options");
28 console.log(options);
29 console.log("user");
30 console.log(user);
26 _.assign(user, { 31 _.assign(user, {
27 role: Users.roles.ADMIN, 32 role: Users.roles.ADMIN,
28 orgId: orgId, 33 orgId: orgId,
29 firstName: options.profile.firstName, 34 firstName: options.profile.name.first,
30 lastName: options.profile.lastName, 35 lastName: options.profile.name.last,
31 }); 36 });
37 console.log(user);
32 return user; 38 return user;
33 }); 39 });
34 40
imports/server/emails/verifyEmail.js
1 import _ from 'lodash'; 1 import _ from 'lodash';
2 import { Accounts } from 'meteor/accounts-base'; 2 import { Accounts } from 'meteor/accounts-base';
3 import { Orgs } from '/imports/collections/orgs/index';
3 4
4 Accounts.config({ 5 Accounts.config({
5 sendVerificationEmail: true 6 sendVerificationEmail: true
6 }); 7 });
7 8
8 Accounts.emailTemplates.verifyEmail = { 9 Accounts.emailTemplates.verifyEmail = {
9 subject() { 10 subject() {
10 return '[YoungDesk] Verify Your Email Address'; 11 return '[YoungDesk] Verify Your Email Address';
11 }, 12 },
12 text(user, url) { 13 text(user, url) {
13 console.log(user);
14 if(user.firstName){
15 const name = user.firstName;
16 }else{
17 const name = user.profile.firstName;
18 }
19 const theUrl = Meteor.absoluteUrl(`back/verifyEmail/${_.last(url.split('/'))}`); 14 const theUrl = Meteor.absoluteUrl(`back/verifyEmail/${_.last(url.split('/'))}`);
15 org = Orgs.findOne({"_id":user.orgId});
20 16
17 OrgUrl = theUrl.replace("http://","http://"+org.slug+".");
21 return ( 18 return (
22 ` 19 `
23 Hello, ${name}! 20 Hello, ${user.firstName}!
24 21
25 22
26 To verify your email address, visit the following link: 23 To verify your email address, visit the following link:
27 24
28 ${theUrl} 25 ${OrgUrl}
29 26
30 If you did not request this verification, please ignore this email. 27 If you did not request this verification, please ignore this email.
31 28
32 ` 29 `
33 ); 30 );