Commit 3540345c5009ccf30a86af176b91dc70978e17b5
1 parent
5251e2b22b
Exists in
master
handful of fixes
- Bump Meteor to 1.4.2. - Bump all NPM packages to latest available versions. - Correct a few ESLint errors that were spotted. - Change casing of file names for components and containers to PascalCase. - Bump version of Base and Meteor in package.json and Index.js component. - Deprecate get-input-value.js module in favor of direct DOM selection via JS.
Showing
37 changed files
with
418 additions
and
393 deletions
Show diff stats
.meteor/.finished-upgraders
.meteor/packages
... | ... | @@ -6,19 +6,19 @@ |
6 | 6 | |
7 | 7 | meteor-base@1.0.4 # Packages every Meteor app needs to have |
8 | 8 | mobile-experience@1.0.4 # Packages for a great mobile UX |
9 | -mongo@1.1.10 # The database Meteor supports right now | |
10 | -reactive-var@1.0.10 # Reactive variable for tracker | |
11 | -session@1.1.6 | |
12 | -tracker@1.1.0 # Meteor's client-side reactive programming library | |
9 | +mongo@1.1.14 # The database Meteor supports right now | |
10 | +reactive-var@1.0.11 # Reactive variable for tracker | |
11 | +session@1.1.7 | |
12 | +tracker@1.1.1 # Meteor's client-side reactive programming library | |
13 | 13 | |
14 | -standard-minifier-css@1.1.8 # CSS minifier run for production mode | |
15 | -standard-minifier-js@1.1.8 # JS minifier run for production mode | |
16 | -es5-shim@4.6.13 # ECMAScript 5 compatibility for older browsers. | |
17 | -ecmascript@0.5.7 # Enable ECMAScript2015+ syntax in app code | |
14 | +standard-minifier-css@1.3.2 # CSS minifier run for production mode | |
15 | +standard-minifier-js@1.2.1 # JS minifier run for production mode | |
16 | +es5-shim@4.6.15 # ECMAScript 5 compatibility for older browsers. | |
17 | +ecmascript@0.5.9 # Enable ECMAScript2015+ syntax in app code | |
18 | 18 | |
19 | -accounts-password@1.2.12 | |
20 | -accounts-base@1.2.9 | |
21 | -check@1.2.3 | |
19 | +accounts-password@1.3.1 | |
20 | +accounts-base@1.2.14 | |
21 | +check@1.2.4 | |
22 | 22 | audit-argument-checks@1.0.7 |
23 | 23 | browser-policy@1.0.9 |
24 | 24 | |
... | ... | @@ -32,4 +32,5 @@ practicalmeteor:mocha |
32 | 32 | xolvio:backdoor |
33 | 33 | mdg:validated-method |
34 | 34 | dburles:factory@1.0.0 |
35 | -ddp-rate-limiter@1.0.5 | |
35 | +ddp-rate-limiter@1.0.6 | |
36 | +shell-server | ... | ... |
.meteor/release
.meteor/versions
1 | -accounts-base@1.2.10 | |
2 | -accounts-password@1.2.14 | |
1 | +accounts-base@1.2.14 | |
2 | +accounts-password@1.3.1 | |
3 | 3 | alanning:roles@1.2.15 |
4 | -aldeed:collection2@2.9.1 | |
5 | -aldeed:collection2-core@1.1.1 | |
6 | -aldeed:schema-deny@1.0.1 | |
7 | -aldeed:schema-index@1.0.1 | |
4 | +aldeed:collection2@2.10.0 | |
5 | +aldeed:collection2-core@1.2.0 | |
6 | +aldeed:schema-deny@1.1.0 | |
7 | +aldeed:schema-index@1.1.0 | |
8 | 8 | aldeed:simple-schema@1.5.3 |
9 | 9 | allow-deny@1.0.5 |
10 | 10 | audit-argument-checks@1.0.7 |
11 | -autoupdate@1.2.11 | |
12 | -babel-compiler@6.9.0 | |
13 | -babel-runtime@0.1.10 | |
14 | -base64@1.0.9 | |
15 | -binary-heap@1.0.9 | |
16 | -blaze@2.1.8 | |
17 | -blaze-tools@1.0.9 | |
18 | -boilerplate-generator@1.0.9 | |
11 | +autoupdate@1.3.12 | |
12 | +babel-compiler@6.13.0 | |
13 | +babel-runtime@0.1.12 | |
14 | +base64@1.0.10 | |
15 | +binary-heap@1.0.10 | |
16 | +blaze@2.1.9 | |
17 | +blaze-tools@1.0.10 | |
18 | +boilerplate-generator@1.0.11 | |
19 | 19 | browser-policy@1.0.9 |
20 | -browser-policy-common@1.0.10 | |
21 | -browser-policy-content@1.0.11 | |
22 | -browser-policy-framing@1.0.11 | |
23 | -caching-compiler@1.0.6 | |
24 | -caching-html-compiler@1.0.6 | |
25 | -callback-hook@1.0.9 | |
26 | -check@1.2.3 | |
27 | -coffeescript@1.1.4 | |
20 | +browser-policy-common@1.0.11 | |
21 | +browser-policy-content@1.0.12 | |
22 | +browser-policy-framing@1.0.12 | |
23 | +caching-compiler@1.1.8 | |
24 | +caching-html-compiler@1.0.7 | |
25 | +callback-hook@1.0.10 | |
26 | +check@1.2.4 | |
27 | +coffeescript@1.11.1_2 | |
28 | 28 | dburles:factory@1.1.0 |
29 | 29 | ddp@1.2.5 |
30 | -ddp-client@1.2.9 | |
31 | -ddp-common@1.2.6 | |
32 | -ddp-rate-limiter@1.0.5 | |
33 | -ddp-server@1.2.10 | |
30 | +ddp-client@1.3.2 | |
31 | +ddp-common@1.2.7 | |
32 | +ddp-rate-limiter@1.0.6 | |
33 | +ddp-server@1.3.11 | |
34 | 34 | deps@1.0.12 |
35 | -diff-sequence@1.0.6 | |
36 | -ecmascript@0.5.7 | |
37 | -ecmascript-runtime@0.3.13 | |
38 | -ejson@1.0.12 | |
39 | -email@1.1.16 | |
40 | -es5-shim@4.6.13 | |
41 | -fastclick@1.0.12 | |
42 | -fortawesome:fontawesome@4.5.0 | |
43 | -fourseven:scss@3.8.1 | |
44 | -geojson-utils@1.0.9 | |
35 | +diff-sequence@1.0.7 | |
36 | +ecmascript@0.5.9 | |
37 | +ecmascript-runtime@0.3.15 | |
38 | +ejson@1.0.13 | |
39 | +email@1.1.18 | |
40 | +es5-shim@4.6.15 | |
41 | +fastclick@1.0.13 | |
42 | +fortawesome:fontawesome@4.6.3 | |
43 | +fourseven:scss@3.10.0 | |
44 | +geojson-utils@1.0.10 | |
45 | 45 | hot-code-push@1.0.4 |
46 | -html-tools@1.0.10 | |
47 | -htmljs@1.0.10 | |
48 | -http@1.1.8 | |
49 | -id-map@1.0.8 | |
50 | -jquery@1.11.9 | |
51 | -launch-screen@1.0.12 | |
46 | +html-tools@1.0.11 | |
47 | +htmljs@1.0.11 | |
48 | +http@1.2.10 | |
49 | +id-map@1.0.9 | |
50 | +jquery@1.11.10 | |
51 | +launch-screen@1.1.0 | |
52 | 52 | livedata@1.0.18 |
53 | -localstorage@1.0.11 | |
54 | -logging@1.1.14 | |
53 | +localstorage@1.0.12 | |
54 | +logging@1.1.16 | |
55 | 55 | mdg:validated-method@1.1.0 |
56 | 56 | mdg:validation-error@0.5.1 |
57 | -meteor@1.2.16 | |
57 | +meteor@1.6.0 | |
58 | 58 | meteor-base@1.0.4 |
59 | -minifier-css@1.2.13 | |
60 | -minifier-js@1.2.13 | |
61 | -minimongo@1.0.17 | |
59 | +minifier-css@1.2.15 | |
60 | +minifier-js@1.2.15 | |
61 | +minimongo@1.0.18 | |
62 | 62 | mobile-experience@1.0.4 |
63 | -mobile-status-bar@1.0.12 | |
64 | -modules@0.7.5 | |
65 | -modules-runtime@0.7.5 | |
66 | -mongo@1.1.10 | |
67 | -mongo-id@1.0.5 | |
68 | -npm-bcrypt@0.8.7_1 | |
69 | -npm-mongo@1.5.45 | |
70 | -observe-sequence@1.0.12 | |
71 | -ordered-dict@1.0.8 | |
63 | +mobile-status-bar@1.0.13 | |
64 | +modules@0.7.7 | |
65 | +modules-runtime@0.7.7 | |
66 | +mongo@1.1.14 | |
67 | +mongo-id@1.0.6 | |
68 | +npm-bcrypt@0.9.2 | |
69 | +npm-mongo@2.2.11_2 | |
70 | +observe-sequence@1.0.14 | |
71 | +ordered-dict@1.0.9 | |
72 | 72 | practicalmeteor:chai@2.1.0_1 |
73 | 73 | practicalmeteor:loglevel@1.2.0_2 |
74 | 74 | practicalmeteor:mocha@2.4.5_6 |
75 | 75 | practicalmeteor:mocha-core@1.0.1 |
76 | 76 | practicalmeteor:sinon@1.14.1_2 |
77 | -promise@0.8.3 | |
77 | +promise@0.8.8 | |
78 | 78 | raix:eventemitter@0.1.3 |
79 | 79 | random@1.0.10 |
80 | -rate-limit@1.0.5 | |
80 | +rate-limit@1.0.6 | |
81 | 81 | reactive-dict@1.1.8 |
82 | -reactive-var@1.0.10 | |
83 | -reload@1.1.10 | |
84 | -retry@1.0.8 | |
85 | -routepolicy@1.0.11 | |
86 | -service-configuration@1.0.10 | |
87 | -session@1.1.6 | |
88 | -sha@1.0.8 | |
89 | -spacebars@1.0.12 | |
90 | -spacebars-compiler@1.0.12 | |
91 | -srp@1.0.9 | |
92 | -standard-minifier-css@1.1.8 | |
93 | -standard-minifier-js@1.1.8 | |
94 | -static-html@1.1.11 | |
95 | -templating@1.1.14 | |
96 | -templating-tools@1.0.4 | |
82 | +reactive-var@1.0.11 | |
83 | +reload@1.1.11 | |
84 | +retry@1.0.9 | |
85 | +routepolicy@1.0.12 | |
86 | +service-configuration@1.0.11 | |
87 | +session@1.1.7 | |
88 | +sha@1.0.9 | |
89 | +shell-server@0.2.1 | |
90 | +spacebars@1.0.13 | |
91 | +spacebars-compiler@1.0.13 | |
92 | +srp@1.0.10 | |
93 | +standard-minifier-css@1.3.2 | |
94 | +standard-minifier-js@1.2.1 | |
95 | +static-html@1.1.13 | |
96 | +templating@1.2.15 | |
97 | +templating-compiler@1.2.15 | |
98 | +templating-runtime@1.2.15 | |
99 | +templating-tools@1.0.5 | |
97 | 100 | themeteorchef:bert@2.1.1 |
98 | 101 | tmeasday:test-reporter-helpers@0.2.1 |
99 | -tracker@1.1.0 | |
100 | -ui@1.0.11 | |
101 | -underscore@1.0.9 | |
102 | -url@1.0.10 | |
103 | -webapp@1.3.10 | |
102 | +tracker@1.1.1 | |
103 | +ui@1.0.12 | |
104 | +underscore@1.0.10 | |
105 | +url@1.0.11 | |
106 | +webapp@1.3.12 | |
104 | 107 | webapp-hashing@1.0.9 |
105 | -xolvio:backdoor@0.2.0 | |
108 | +xolvio:backdoor@0.2.1 | |
106 | 109 | xolvio:cleaner@0.3.1 | ... | ... |
README.md
imports/api/documents/documents.js
imports/api/documents/methods.js
1 | -import { Documents } from './documents'; | |
2 | 1 | import { SimpleSchema } from 'meteor/aldeed:simple-schema'; |
3 | 2 | import { ValidatedMethod } from 'meteor/mdg:validated-method'; |
3 | +import { Documents } from './documents'; | |
4 | 4 | import { rateLimit } from '../../modules/rate-limit.js'; |
5 | 5 | |
6 | 6 | export const insertDocument = new ValidatedMethod({ | ... | ... |
imports/modules/get-input-value.js
imports/startup/client/routes.js
... | ... | @@ -2,14 +2,14 @@ import React from 'react'; |
2 | 2 | import { render } from 'react-dom'; |
3 | 3 | import { Router, Route, IndexRoute, browserHistory } from 'react-router'; |
4 | 4 | import { Meteor } from 'meteor/meteor'; |
5 | -import { App } from '../../ui/layouts/app'; | |
6 | -import { Documents } from '../../ui/pages/documents'; | |
7 | -import { Index } from '../../ui/pages/index'; | |
8 | -import { Login } from '../../ui/pages/login'; | |
9 | -import { NotFound } from '../../ui/pages/not-found'; | |
10 | -import { RecoverPassword } from '../../ui/pages/recover-password'; | |
11 | -import { ResetPassword } from '../../ui/pages/reset-password'; | |
12 | -import { Signup } from '../../ui/pages/signup'; | |
5 | +import { App } from '../../ui/layouts/App.js'; | |
6 | +import { Documents } from '../../ui/pages/Documents.js'; | |
7 | +import { Index } from '../../ui/pages/Index.js'; | |
8 | +import { Login } from '../../ui/pages/Login.js'; | |
9 | +import { NotFound } from '../../ui/pages/NotFound.js'; | |
10 | +import { RecoverPassword } from '../../ui/pages/RecoverPassword.js'; | |
11 | +import { ResetPassword } from '../../ui/pages/ResetPassword.js'; | |
12 | +import { Signup } from '../../ui/pages/Signup.js'; | |
13 | 13 | |
14 | 14 | const requireAuth = (nextState, replace) => { |
15 | 15 | if (!Meteor.loggingIn() && !Meteor.userId()) { | ... | ... |
imports/ui/components/AddDocument.js
... | ... | @@ -0,0 +1,34 @@ |
1 | +import React from 'react'; | |
2 | +import { FormGroup, FormControl } from 'react-bootstrap'; | |
3 | +import { Bert } from 'meteor/themeteorchef:bert'; | |
4 | +import { insertDocument } from '../../api/documents/methods.js'; | |
5 | + | |
6 | +const handleInsertDocument = (event) => { | |
7 | + const target = event.target; | |
8 | + const title = target.value.trim(); | |
9 | + | |
10 | + if (title !== '' && event.keyCode === 13) { | |
11 | + insertDocument.call({ | |
12 | + title, | |
13 | + }, (error) => { | |
14 | + if (error) { | |
15 | + Bert.alert(error.reason, 'danger'); | |
16 | + } else { | |
17 | + target.value = ''; | |
18 | + Bert.alert('Document added!', 'success'); | |
19 | + } | |
20 | + }); | |
21 | + } | |
22 | +}; | |
23 | + | |
24 | +const AddDocument = () => ( | |
25 | + <FormGroup> | |
26 | + <FormControl | |
27 | + type="text" | |
28 | + onKeyUp={ handleInsertDocument } | |
29 | + placeholder="Type a document title and press enter..." | |
30 | + /> | |
31 | + </FormGroup> | |
32 | +); | |
33 | + | |
34 | +export default AddDocument; | ... | ... |
imports/ui/components/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/ui/components/AuthenticatedNavigation.js
... | ... | @@ -0,0 +1,33 @@ |
1 | +import React from 'react'; | |
2 | +import { browserHistory } from 'react-router'; | |
3 | +import { IndexLinkContainer, 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 | + <IndexLinkContainer to="/"> | |
19 | + <NavItem eventKey={ 1 } href="/">Index</NavItem> | |
20 | + </IndexLinkContainer> | |
21 | + <LinkContainer to="/documents"> | |
22 | + <NavItem eventKey={ 2 } href="/documents">Documents</NavItem> | |
23 | + </LinkContainer> | |
24 | + </Nav> | |
25 | + <Nav pullRight> | |
26 | + <NavDropdown eventKey={ 3 } title={ userName() } id="basic-nav-dropdown"> | |
27 | + <MenuItem eventKey={ 3.1 } onClick={ handleLogout }>Logout</MenuItem> | |
28 | + </NavDropdown> | |
29 | + </Nav> | |
30 | + </div> | |
31 | +); | |
32 | + | |
33 | +export default AuthenticatedNavigation; | ... | ... |
imports/ui/components/DocumentsList.js
... | ... | @@ -0,0 +1,18 @@ |
1 | +import React from 'react'; | |
2 | +import { ListGroup, Alert } from 'react-bootstrap'; | |
3 | +import { Document } from './Document.js'; | |
4 | + | |
5 | +const DocumentsList = ({ documents }) => ( | |
6 | + documents.length > 0 ? <ListGroup className="documents-list"> | |
7 | + {documents.map(doc => ( | |
8 | + <Document key={ doc._id } document={ doc } /> | |
9 | + ))} | |
10 | + </ListGroup> : | |
11 | + <Alert bsStyle="warning">No documents yet.</Alert> | |
12 | +); | |
13 | + | |
14 | +DocumentsList.propTypes = { | |
15 | + documents: React.PropTypes.array, | |
16 | +}; | |
17 | + | |
18 | +export default DocumentsList; | ... | ... |
imports/ui/components/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/ui/components/add-document.js
... | ... | @@ -1,32 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { FormGroup, FormControl } from 'react-bootstrap'; | |
3 | -import { Bert } from 'meteor/themeteorchef:bert'; | |
4 | -import { insertDocument } from '../../api/documents/methods.js'; | |
5 | - | |
6 | -const handleInsertDocument = (event) => { | |
7 | - const target = event.target; | |
8 | - const title = target.value.trim(); | |
9 | - | |
10 | - if (title !== '' && event.keyCode === 13) { | |
11 | - insertDocument.call({ | |
12 | - title, | |
13 | - }, (error) => { | |
14 | - if (error) { | |
15 | - Bert.alert(error.reason, 'danger'); | |
16 | - } else { | |
17 | - target.value = ''; | |
18 | - Bert.alert('Document added!', 'success'); | |
19 | - } | |
20 | - }); | |
21 | - } | |
22 | -}; | |
23 | - | |
24 | -export const AddDocument = () => ( | |
25 | - <FormGroup> | |
26 | - <FormControl | |
27 | - type="text" | |
28 | - onKeyUp={ handleInsertDocument } | |
29 | - placeholder="Type a document title and press enter..." | |
30 | - /> | |
31 | - </FormGroup> | |
32 | -); |
imports/ui/components/app-navigation.js
... | ... | @@ -1,29 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { Navbar } from 'react-bootstrap'; | |
3 | -import { Link } from 'react-router'; | |
4 | -import { PublicNavigation } from './public-navigation'; | |
5 | -import { AuthenticatedNavigation } from './authenticated-navigation'; | |
6 | - | |
7 | -export class AppNavigation extends React.Component { | |
8 | - renderNavigation(hasUser) { | |
9 | - return hasUser ? <AuthenticatedNavigation /> : <PublicNavigation />; | |
10 | - } | |
11 | - | |
12 | - render() { | |
13 | - return <Navbar> | |
14 | - <Navbar.Header> | |
15 | - <Navbar.Brand> | |
16 | - <Link to="/">Application Name</Link> | |
17 | - </Navbar.Brand> | |
18 | - <Navbar.Toggle /> | |
19 | - </Navbar.Header> | |
20 | - <Navbar.Collapse> | |
21 | - { this.renderNavigation(this.props.hasUser) } | |
22 | - </Navbar.Collapse> | |
23 | - </Navbar>; | |
24 | - } | |
25 | -} | |
26 | - | |
27 | -AppNavigation.propTypes = { | |
28 | - hasUser: React.PropTypes.object, | |
29 | -}; |
imports/ui/components/authenticated-navigation.js
... | ... | @@ -1,31 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { browserHistory } from 'react-router'; | |
3 | -import { IndexLinkContainer, 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 | -export const AuthenticatedNavigation = () => ( | |
16 | - <div> | |
17 | - <Nav> | |
18 | - <IndexLinkContainer to="/"> | |
19 | - <NavItem eventKey={ 1 } href="/">Index</NavItem> | |
20 | - </IndexLinkContainer> | |
21 | - <LinkContainer to="/documents"> | |
22 | - <NavItem eventKey={ 2 } href="/documents">Documents</NavItem> | |
23 | - </LinkContainer> | |
24 | - </Nav> | |
25 | - <Nav pullRight> | |
26 | - <NavDropdown eventKey={ 3 } title={ userName() } id="basic-nav-dropdown"> | |
27 | - <MenuItem eventKey={ 3.1 } onClick={ handleLogout }>Logout</MenuItem> | |
28 | - </NavDropdown> | |
29 | - </Nav> | |
30 | - </div> | |
31 | -); |
imports/ui/components/document.js
... | ... | @@ -37,7 +37,7 @@ const handleRemoveDocument = (documentId, event) => { |
37 | 37 | } |
38 | 38 | }; |
39 | 39 | |
40 | -export const Document = ({ document }) => ( | |
40 | +const Document = ({ document }) => ( | |
41 | 41 | <ListGroupItem key={ document._id }> |
42 | 42 | <Row> |
43 | 43 | <Col xs={ 8 } sm={ 10 }> |
... | ... | @@ -58,3 +58,9 @@ export const Document = ({ document }) => ( |
58 | 58 | </Row> |
59 | 59 | </ListGroupItem> |
60 | 60 | ); |
61 | + | |
62 | +Document.propTypes = { | |
63 | + document: React.PropTypes.object, | |
64 | +}; | |
65 | + | |
66 | +export default Document; | ... | ... |
imports/ui/components/documents-list.js
... | ... | @@ -1,16 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { ListGroup, Alert } from 'react-bootstrap'; | |
3 | -import { Document } from './document.js'; | |
4 | - | |
5 | -export const DocumentsList = ({ documents }) => ( | |
6 | - documents.length > 0 ? <ListGroup className="documents-list"> | |
7 | - {documents.map((doc) => ( | |
8 | - <Document key={ doc._id } document={ doc } /> | |
9 | - ))} | |
10 | - </ListGroup> : | |
11 | - <Alert bsStyle="warning">No documents yet.</Alert> | |
12 | -); | |
13 | - | |
14 | -DocumentsList.propTypes = { | |
15 | - documents: React.PropTypes.array, | |
16 | -}; |
imports/ui/components/loading.js
imports/ui/components/public-navigation.js
... | ... | @@ -1,14 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { LinkContainer } from 'react-router-bootstrap'; | |
3 | -import { Nav, NavItem } from 'react-bootstrap'; | |
4 | - | |
5 | -export 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 | -); |
imports/ui/containers/AppNavigation.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/ui/containers/DocumentsList.js
... | ... | @@ -0,0 +1,15 @@ |
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'); | |
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/app-navigation.js
... | ... | @@ -1,9 +0,0 @@ |
1 | -import { composeWithTracker } from 'react-komposer'; | |
2 | -import { Meteor } from 'meteor/meteor'; | |
3 | -import { AppNavigation } from '../components/app-navigation'; | |
4 | - | |
5 | -const composer = (props, onData) => { | |
6 | - onData(null, { hasUser: Meteor.user() }); | |
7 | -}; | |
8 | - | |
9 | -export default composeWithTracker(composer, {}, {}, { pure: false })(AppNavigation); |
imports/ui/containers/documents-list.js
... | ... | @@ -1,15 +0,0 @@ |
1 | -import { composeWithTracker } from 'react-komposer'; | |
2 | -import { Documents } from '../../api/documents/documents.js'; | |
3 | -import { DocumentsList } from '../components/documents-list.js'; | |
4 | -import { Loading } from '../components/loading.js'; | |
5 | -import { Meteor } from 'meteor/meteor'; | |
6 | - | |
7 | -const composer = (params, onData) => { | |
8 | - const subscription = Meteor.subscribe('documents'); | |
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/layouts/app.js
1 | 1 | import React from 'react'; |
2 | 2 | import { Grid } from 'react-bootstrap'; |
3 | -import AppNavigation from '../containers/app-navigation'; | |
3 | +import AppNavigation from '../containers/AppNavigation.js'; | |
4 | 4 | |
5 | -export const App = React.createClass({ | |
6 | - propTypes: { | |
7 | - children: React.PropTypes.element.isRequired, | |
8 | - }, | |
9 | - render() { | |
10 | - return <div> | |
11 | - <AppNavigation /> | |
12 | - <Grid> | |
13 | - { this.props.children } | |
14 | - </Grid> | |
15 | - </div>; | |
16 | - }, | |
17 | -}); | |
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/NotFound.js
... | ... | @@ -0,0 +1,10 @@ |
1 | +import React from 'react'; | |
2 | +import { Alert } from 'react-bootstrap'; | |
3 | + | |
4 | +const NotFound = () => ( | |
5 | + <Alert bsStyle="danger"> | |
6 | + <p><strong>Error [404]</strong>: { window.location.pathname } does not exist.</p> | |
7 | + </Alert> | |
8 | +); | |
9 | + | |
10 | +export default NotFound; | ... | ... |
imports/ui/pages/RecoverPassword.js
... | ... | @@ -0,0 +1,35 @@ |
1 | +import React from 'react'; | |
2 | +import { Row, Col, Alert, FormGroup, FormControl, Button } from 'react-bootstrap'; | |
3 | +import { handleRecoverPassword } from '../../modules/recover-password'; | |
4 | + | |
5 | +export default class RecoverPassword extends React.Component { | |
6 | + componentDidMount() { | |
7 | + handleRecoverPassword({ component: this }); | |
8 | + } | |
9 | + | |
10 | + handleSubmit() { | |
11 | + this.preventDefault(); | |
12 | + } | |
13 | + | |
14 | + render() { | |
15 | + return (<Row> | |
16 | + <Col xs={ 12 } sm={ 6 } md={ 4 }> | |
17 | + <h4 className="page-header">Recover Password</h4> | |
18 | + <Alert bsStyle="info"> | |
19 | + Enter your email address below to receive a link to reset your password. | |
20 | + </Alert> | |
21 | + <form ref="recoverPassword" className="recover-password" onSubmit={ this.handleSubmit }> | |
22 | + <FormGroup> | |
23 | + <FormControl | |
24 | + type="email" | |
25 | + ref="emailAddress" | |
26 | + name="emailAddress" | |
27 | + placeholder="Email Address" | |
28 | + /> | |
29 | + </FormGroup> | |
30 | + <Button type="submit" bsStyle="success">Recover Password</Button> | |
31 | + </form> | |
32 | + </Col> | |
33 | + </Row>); | |
34 | + } | |
35 | +} | ... | ... |
imports/ui/pages/ResetPassword.js
... | ... | @@ -0,0 +1,50 @@ |
1 | +import React from 'react'; | |
2 | +import { Row, Col, Alert, FormGroup, ControlLabel, FormControl, Button } from 'react-bootstrap'; | |
3 | +import { handleResetPassword } from '../../modules/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() { | |
11 | + this.preventDefault(); | |
12 | + } | |
13 | + | |
14 | + render() { | |
15 | + return (<Row> | |
16 | + <Col xs={ 12 } sm={ 6 } md={ 4 }> | |
17 | + <h4 className="page-header">Reset Password</h4> | |
18 | + <Alert bsStyle="info"> | |
19 | + To reset your password, enter a new one below. You will be logged in | |
20 | +with your new password. | |
21 | + </Alert> | |
22 | + <form ref="resetPassword" className="reset-password" onSubmit={ this.handleSubmit }> | |
23 | + <FormGroup> | |
24 | + <ControlLabel>New Password</ControlLabel> | |
25 | + <FormControl | |
26 | + type="password" | |
27 | + ref="newPassword" | |
28 | + name="newPassword" | |
29 | + placeholder="New Password" | |
30 | + /> | |
31 | + </FormGroup> | |
32 | + <FormGroup> | |
33 | + <ControlLabel>Repeat New Password</ControlLabel> | |
34 | + <FormControl | |
35 | + type="password" | |
36 | + ref="repeatNewPassword" | |
37 | + name="repeatNewPassword" | |
38 | + placeholder="Repeat New Password" | |
39 | + /> | |
40 | + </FormGroup> | |
41 | + <Button type="submit" bsStyle="success">Reset Password & Login</Button> | |
42 | + </form> | |
43 | + </Col> | |
44 | + </Row>); | |
45 | + } | |
46 | +} | |
47 | + | |
48 | +ResetPassword.propTypes = { | |
49 | + params: React.PropTypes.object, | |
50 | +}; | ... | ... |
imports/ui/pages/documents.js
1 | 1 | import React from 'react'; |
2 | 2 | import { Row, Col } from 'react-bootstrap'; |
3 | -import DocumentsList from '../containers/documents-list.js'; | |
4 | -import { AddDocument } from '../components/add-document.js'; | |
3 | +import DocumentsList from '../containers/DocumentsList.js'; | |
4 | +import { AddDocument } from '../components/AddDocument.js'; | |
5 | 5 | |
6 | -export const Documents = () => ( | |
6 | +const Documents = () => ( | |
7 | 7 | <Row> |
8 | 8 | <Col xs={ 12 }> |
9 | 9 | <h4 className="page-header">Documents</h4> |
... | ... | @@ -12,3 +12,5 @@ export const Documents = () => ( |
12 | 12 | </Col> |
13 | 13 | </Row> |
14 | 14 | ); |
15 | + | |
16 | +export default Documents; | ... | ... |
imports/ui/pages/index.js
1 | 1 | import React from 'react'; |
2 | 2 | import { Jumbotron } from 'react-bootstrap'; |
3 | 3 | |
4 | -export const Index = () => ( | |
4 | +const Index = () => ( | |
5 | 5 | <Jumbotron className="text-center"> |
6 | 6 | <h2>Base</h2> |
7 | 7 | <p>A starting point for Meteor applications.</p> |
8 | 8 | <p><a className="btn btn-success" href="https://themeteorchef.com/base" role="button">Read the Documentation</a></p> |
9 | - <p style={ { fontSize: '16px', color: '#aaa' } }>Currently at v4.7.0</p> | |
9 | + <p style={ { fontSize: '16px', color: '#aaa' } }>Currently at v4.8.0</p> | |
10 | 10 | </Jumbotron> |
11 | 11 | ); |
12 | + | |
13 | +export default Index; | ... | ... |
imports/ui/pages/login.js
... | ... | @@ -3,17 +3,17 @@ import { Link } from 'react-router'; |
3 | 3 | import { Row, Col, FormGroup, ControlLabel, FormControl, Button } from 'react-bootstrap'; |
4 | 4 | import { handleLogin } from '../../modules/login'; |
5 | 5 | |
6 | -export class Login extends React.Component { | |
6 | +export default class Login extends React.Component { | |
7 | 7 | componentDidMount() { |
8 | 8 | handleLogin({ component: this }); |
9 | 9 | } |
10 | 10 | |
11 | - handleSubmit(event) { | |
12 | - event.preventDefault(); | |
11 | + handleSubmit() { | |
12 | + this.preventDefault(); | |
13 | 13 | } |
14 | 14 | |
15 | 15 | render() { |
16 | - return <Row> | |
16 | + return (<Row> | |
17 | 17 | <Col xs={ 12 } sm={ 6 } md={ 4 }> |
18 | 18 | <h4 className="page-header">Login</h4> |
19 | 19 | <form ref="login" className="login" onSubmit={ this.handleSubmit }> |
... | ... | @@ -41,6 +41,6 @@ export class Login extends React.Component { |
41 | 41 | <Button type="submit" bsStyle="success">Login</Button> |
42 | 42 | </form> |
43 | 43 | </Col> |
44 | - </Row>; | |
44 | + </Row>); | |
45 | 45 | } |
46 | 46 | } | ... | ... |
imports/ui/pages/not-found.js
imports/ui/pages/recover-password.js
... | ... | @@ -1,35 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { Row, Col, Alert, FormGroup, FormControl, Button } from 'react-bootstrap'; | |
3 | -import { handleRecoverPassword } from '../../modules/recover-password'; | |
4 | - | |
5 | -export 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 <Row> | |
16 | - <Col xs={ 12 } sm={ 6 } md={ 4 }> | |
17 | - <h4 className="page-header">Recover Password</h4> | |
18 | - <Alert bsStyle="info"> | |
19 | - Enter your email address below to receive a link to reset your password. | |
20 | - </Alert> | |
21 | - <form ref="recoverPassword" className="recover-password" onSubmit={ this.handleSubmit }> | |
22 | - <FormGroup> | |
23 | - <FormControl | |
24 | - type="email" | |
25 | - ref="emailAddress" | |
26 | - name="emailAddress" | |
27 | - placeholder="Email Address" | |
28 | - /> | |
29 | - </FormGroup> | |
30 | - <Button type="submit" bsStyle="success">Recover Password</Button> | |
31 | - </form> | |
32 | - </Col> | |
33 | - </Row>; | |
34 | - } | |
35 | -} |
imports/ui/pages/reset-password.js
... | ... | @@ -1,53 +0,0 @@ |
1 | -import React from 'react'; | |
2 | -import { Row, Col, Alert, FormGroup, ControlLabel, FormControl, Button } from 'react-bootstrap'; | |
3 | -import { handleResetPassword } from '../../modules/reset-password'; | |
4 | - | |
5 | -export class ResetPassword extends React.Component { | |
6 | - componentDidMount() { | |
7 | - handleResetPassword({ | |
8 | - component: this, | |
9 | - token: this.props.params.token, | |
10 | - }); | |
11 | - } | |
12 | - | |
13 | - handleSubmit(event) { | |
14 | - event.preventDefault(); | |
15 | - } | |
16 | - | |
17 | - render() { | |
18 | - return <Row> | |
19 | - <Col xs={ 12 } sm={ 6 } md={ 4 }> | |
20 | - <h4 className="page-header">Reset Password</h4> | |
21 | - <Alert bsStyle="info"> | |
22 | - To reset your password, enter a new one below. You will be logged in | |
23 | -with your new password. | |
24 | - </Alert> | |
25 | - <form ref="resetPassword" className="reset-password" onSubmit={ this.handleSubmit }> | |
26 | - <FormGroup> | |
27 | - <ControlLabel>New Password</ControlLabel> | |
28 | - <FormControl | |
29 | - type="password" | |
30 | - ref="newPassword" | |
31 | - name="newPassword" | |
32 | - placeholder="New Password" | |
33 | - /> | |
34 | - </FormGroup> | |
35 | - <FormGroup> | |
36 | - <ControlLabel>Repeat New Password</ControlLabel> | |
37 | - <FormControl | |
38 | - type="password" | |
39 | - ref="repeatNewPassword" | |
40 | - name="repeatNewPassword" | |
41 | - placeholder="Repeat New Password" | |
42 | - /> | |
43 | - </FormGroup> | |
44 | - <Button type="submit" bsStyle="success">Reset Password & Login</Button> | |
45 | - </form> | |
46 | - </Col> | |
47 | - </Row>; | |
48 | - } | |
49 | -} | |
50 | - | |
51 | -ResetPassword.propTypes = { | |
52 | - params: React.PropTypes.object, | |
53 | -}; |
imports/ui/pages/signup.js
... | ... | @@ -3,17 +3,17 @@ import { Link } from 'react-router'; |
3 | 3 | import { Row, Col, FormGroup, ControlLabel, FormControl, Button } from 'react-bootstrap'; |
4 | 4 | import { handleSignup } from '../../modules/signup'; |
5 | 5 | |
6 | -export class Signup extends React.Component { | |
6 | +export default class Signup extends React.Component { | |
7 | 7 | componentDidMount() { |
8 | 8 | handleSignup({ component: this }); |
9 | 9 | } |
10 | 10 | |
11 | - handleSubmit(event) { | |
12 | - event.preventDefault(); | |
11 | + handleSubmit() { | |
12 | + this.preventDefault(); | |
13 | 13 | } |
14 | 14 | |
15 | 15 | render() { |
16 | - return <Row> | |
16 | + return (<Row> | |
17 | 17 | <Col xs={ 12 } sm={ 6 } md={ 4 }> |
18 | 18 | <h4 className="page-header">Sign Up</h4> |
19 | 19 | <form ref="signup" className="signup" onSubmit={ this.handleSubmit }> |
... | ... | @@ -63,6 +63,6 @@ export class Signup extends React.Component { |
63 | 63 | </form> |
64 | 64 | <p>Already have an account? <Link to="/login">Log In</Link>.</p> |
65 | 65 | </Col> |
66 | - </Row>; | |
66 | + </Row>); | |
67 | 67 | } |
68 | 68 | } | ... | ... |
package.json
... | ... | @@ -11,12 +11,13 @@ |
11 | 11 | "production": "meteor deploy production.meteor.com --settings settings-production.json" |
12 | 12 | }, |
13 | 13 | "devDependencies": { |
14 | - "chimp": "^0.39.1", | |
15 | - "eslint": "^2.13.1", | |
16 | - "eslint-config-airbnb": "^9.0.1", | |
17 | - "eslint-plugin-jsx-a11y": "^1.5.5", | |
18 | - "eslint-plugin-meteor": "^3.6.0", | |
19 | - "eslint-plugin-react": "^5.2.2", | |
14 | + "chimp": "^0.41.2", | |
15 | + "eslint": "^3.8.1", | |
16 | + "eslint-config-airbnb": "^12.0.0", | |
17 | + "eslint-plugin-import": "^1.16.0", | |
18 | + "eslint-plugin-jsx-a11y": "^2.2.3", | |
19 | + "eslint-plugin-meteor": "^4.0.1", | |
20 | + "eslint-plugin-react": "^6.4.1", | |
20 | 21 | "faker": "^3.1.0" |
21 | 22 | }, |
22 | 23 | "eslintConfig": { |
... | ... | @@ -34,6 +35,9 @@ |
34 | 35 | "plugin:meteor/guide", |
35 | 36 | "plugin:react/recommended" |
36 | 37 | ], |
38 | + "env": { | |
39 | + "browser": true | |
40 | + }, | |
37 | 41 | "globals": { |
38 | 42 | "server": false, |
39 | 43 | "browser": false, |
... | ... | @@ -41,6 +45,8 @@ |
41 | 45 | }, |
42 | 46 | "rules": { |
43 | 47 | "import/no-unresolved": 0, |
48 | + "import/no-extraneous-dependencies": 0, | |
49 | + "import/extensions": 0, | |
44 | 50 | "no-underscore-dangle": [ |
45 | 51 | "error", |
46 | 52 | { |
... | ... | @@ -56,15 +62,16 @@ |
56 | 62 | } |
57 | 63 | }, |
58 | 64 | "dependencies": { |
65 | + "bcrypt": "^0.8.7", | |
59 | 66 | "bootstrap": "^3.3.7", |
60 | - "jquery": "^2.2.4", | |
67 | + "jquery": "^3.1.1", | |
61 | 68 | "jquery-validation": "^1.15.1", |
62 | - "react": "^15.3.0", | |
63 | - "react-addons-pure-render-mixin": "^15.2.1", | |
64 | - "react-bootstrap": "^0.30.2", | |
65 | - "react-dom": "^15.3.0", | |
69 | + "react": "^15.3.2", | |
70 | + "react-addons-pure-render-mixin": "^15.3.2", | |
71 | + "react-bootstrap": "^0.30.5", | |
72 | + "react-dom": "^15.3.2", | |
66 | 73 | "react-komposer": "^1.13.1", |
67 | - "react-router": "^2.6.1", | |
74 | + "react-router": "^3.0.0", | |
68 | 75 | "react-router-bootstrap": "^0.23.1" |
69 | 76 | } |
70 | 77 | } | ... | ... |