├── .babelrc
├── .eslintrc.json
├── .gitignore
├── LICENSE
├── PATENTS
├── README.md
├── build
├── app.js
└── index.html
├── lib
├── apollo.js
├── config.js
├── index.html
├── js
│ ├── app.js
│ └── components
│ │ ├── App
│ │ ├── App.js
│ │ ├── Description.js
│ │ ├── Footer.js
│ │ ├── Header.js
│ │ ├── Hero.js
│ │ ├── Login.js
│ │ └── Register.js
│ │ ├── GraphiQL
│ │ └── GraphiQL.js
│ │ └── Home
│ │ ├── Body.js
│ │ ├── Header.js
│ │ ├── Home.js
│ │ └── Logout.js
└── server.js
├── package.json
├── src
├── apollo.js
├── config.js
├── index.html
├── js
│ ├── app.js
│ └── components
│ │ ├── App
│ │ ├── App.js
│ │ ├── Description.js
│ │ ├── Footer.js
│ │ ├── Header.js
│ │ ├── Hero.js
│ │ ├── Login.js
│ │ └── Register.js
│ │ ├── GraphiQL
│ │ └── GraphiQL.js
│ │ └── Home
│ │ ├── Body.js
│ │ ├── Header.js
│ │ ├── Home.js
│ │ └── Logout.js
└── server.js
└── webpack
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "react",
4 | "es2015",
5 | "stage-0"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": "airbnb",
4 | "plugins": [
5 | "react",
6 | "jsx-a11y",
7 | "import",
8 | "flowtype"
9 | ],
10 | "rules": {
11 | "semi": ["error", "always"],
12 | "quotes": ["error", "single", {"allowTemplateLiterals": true}],
13 | "no-param-reassign": ["error", { "props": false }],
14 | "no-underscore-dangle": ["error", { "allowAfterThis": true }],
15 | "flowtype/boolean-style": [
16 | 2,
17 | "boolean"
18 | ],
19 | "flowtype/define-flow-type": 1,
20 | "flowtype/delimiter-dangle": 0,
21 | "flowtype/generic-spacing": [
22 | 2,
23 | "never"
24 | ],
25 | "flowtype/no-weak-types": 0,
26 | "flowtype/require-parameter-type": 0,
27 | "flowtype/require-return-type": 0,
28 | "flowtype/require-valid-file-annotation": 0,
29 | "flowtype/semi": 0,
30 | "flowtype/space-after-type-colon": [
31 | 2,
32 | "always"
33 | ],
34 | "flowtype/space-before-generic-bracket": [
35 | 2,
36 | "never"
37 | ],
38 | "flowtype/space-before-type-colon": [
39 | 2,
40 | "never"
41 | ],
42 | "flowtype/type-id-match": 0,
43 | "flowtype/union-intersection-spacing": [
44 | 2,
45 | "always"
46 | ],
47 | "flowtype/use-flow-type": 1,
48 | "flowtype/valid-syntax": 1,
49 | "react/jsx-filename-extension": 0,
50 | "react/jsx-no-target-blank": 0,
51 | "react/no-unescaped-entities": 0,
52 | "react/forbid-prop-types": 0,
53 | "react/require-default-props": 0,
54 | "class-methods-use-this": 0,
55 | "no-plusplus": 0,
56 | "no-underscore-dangle": 0,
57 | "react/no-array-index-key": 0,
58 | "react/prefer-stateless-function": 0
59 | },
60 | "env": {
61 | "node": true,
62 | "mocha": true
63 | },
64 | "settings": {
65 | "flowtype": {
66 | "onlyFilesWithFlowAnnotation": false
67 | }
68 | },
69 | "globals": {
70 | "window": true,
71 | "localStorage": true
72 | }
73 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | npm-debug.log
4 | data/schema.graphql
5 | .idea/
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD License
2 |
3 | For Relay Starter Kit software
4 |
5 | Copyright (c) 2013-2015, Facebook, Inc.
6 | All rights reserved.
7 |
8 | Redistribution and use in source and binary forms, with or without modification,
9 | are permitted provided that the following conditions are met:
10 |
11 | * Redistributions of source code must retain the above copyright notice, this
12 | list of conditions and the following disclaimer.
13 |
14 | * Redistributions in binary form must reproduce the above copyright notice,
15 | this list of conditions and the following disclaimer in the documentation
16 | and/or other materials provided with the distribution.
17 |
18 | * Neither the name Facebook nor the names of its contributors may be used to
19 | endorse or promote products derived from this software without specific
20 | prior written permission.
21 |
22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
23 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
26 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
27 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 |
--------------------------------------------------------------------------------
/PATENTS:
--------------------------------------------------------------------------------
1 | Additional Grant of Patent Rights Version 2
2 |
3 | "Software" means the Relay Starter Kit software distributed by Facebook, Inc.
4 |
5 | Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software
6 | ("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable
7 | (subject to the termination provision below) license under any Necessary
8 | Claims, to make, have made, use, sell, offer to sell, import, and otherwise
9 | transfer the Software. For avoidance of doubt, no license is granted under
10 | Facebook's rights in any patent claims that are infringed by (i) modifications
11 | to the Software made by you or any third party or (ii) the Software in
12 | combination with any software or other technology.
13 |
14 | The license granted hereunder will terminate, automatically and without notice,
15 | if you (or any of your subsidiaries, corporate affiliates or agents) initiate
16 | directly or indirectly, or take a direct financial interest in, any Patent
17 | Assertion: (i) against Facebook or any of its subsidiaries or corporate
18 | affiliates, (ii) against any party if such Patent Assertion arises in whole or
19 | in part from any software, technology, product or service of Facebook or any of
20 | its subsidiaries or corporate affiliates, or (iii) against any party relating
21 | to the Software. Notwithstanding the foregoing, if Facebook or any of its
22 | subsidiaries or corporate affiliates files a lawsuit alleging patent
23 | infringement against you in the first instance, and you respond by filing a
24 | patent infringement counterclaim in that lawsuit against that party that is
25 | unrelated to the Software, the license granted hereunder will not terminate
26 | under section (i) of this paragraph due to such counterclaim.
27 |
28 | A "Necessary Claim" is a claim of a patent owned by Facebook that is
29 | necessarily infringed by the Software standing alone.
30 |
31 | A "Patent Assertion" is any lawsuit or other action alleging direct, indirect,
32 | or contributory infringement or inducement to infringe any patent, including a
33 | cross-claim or counterclaim.
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #Scaphold.io's React Apollo boilerplate
2 |
3 | Fork this boilerplate code to get started with GraphQL, React, and Apollo.
4 |
5 | **Quickstart:**
6 |
7 | 1) Go to Scaphold.io (https://scaphold.io).
8 |
9 | 2) Create an account and dataset.
10 |
11 | 3) Change the URL in the API manager (config.js) in the boilerplate to point to your unique Scaphold.io API URL.
12 |
13 | 5) Install dependencies: ```npm install```
14 |
15 | 4) Run with: ```npm start```
16 |
17 |
18 | **Deployment:**
19 |
20 | *Note: For development, you only need to run ```npm start```*
21 |
22 | Run ```npm run deploy```.
23 |
24 | This will run two scripts automatically:
25 |
26 | 1) ```npm run build``` to transpile ES6 code from the src/ directory to JavaScript in the lib/ directory.
27 |
28 | 2) ```npm run wp``` to set the environment variable ```process.env.NODE_ENV = 'production'```, allow webpack to build your code from lib/, and save it to the build/ directory.
29 |
--------------------------------------------------------------------------------
/build/index.html:
--------------------------------------------------------------------------------
1 |
React-Apollo Starter Kit for Scaphold.io
--------------------------------------------------------------------------------
/lib/apollo.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _apolloClient = require('apollo-client');
8 |
9 | var _apolloClient2 = _interopRequireDefault(_apolloClient);
10 |
11 | var _config = require('./config');
12 |
13 | var _config2 = _interopRequireDefault(_config);
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | var networkInterface = (0, _apolloClient.createNetworkInterface)({
18 | uri: _config2.default.scapholdUrl
19 | });
20 | networkInterface.use([{
21 | applyMiddleware: function applyMiddleware(req, next) {
22 | if (!req.options.headers) {
23 | req.options.headers = {}; // Create the header object if needed.
24 | }
25 | if (localStorage.getItem('token')) {
26 | req.options.headers.Authorization = 'Bearer ' + localStorage.getItem('token');
27 | }
28 | next();
29 | }
30 | }]);
31 |
32 | var client = new _apolloClient2.default({
33 | networkInterface: networkInterface
34 | });
35 |
36 | exports.default = client;
--------------------------------------------------------------------------------
/lib/config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Modify the config Scaphold URL to point to your specific app.
5 | * Find the URL at the top of the page on Scaphold.io once you've created an app.
6 | * Yup. It's that easy.
7 | */
8 |
9 | var config = {
10 | scapholdUrl: 'https://us-west-2.api.scaphold.io/graphql/react-apollo-starter-kit'
11 | };
12 |
13 | module.exports = config;
--------------------------------------------------------------------------------
/lib/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | React-Apollo Starter Kit for Scaphold.io
10 |
11 |
16 |
17 |
18 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/lib/js/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _react = require('react');
4 |
5 | var _react2 = _interopRequireDefault(_react);
6 |
7 | var _reactDom = require('react-dom');
8 |
9 | var _reactDom2 = _interopRequireDefault(_reactDom);
10 |
11 | var _reactRouter = require('react-router');
12 |
13 | var _reactApollo = require('react-apollo');
14 |
15 | var _App = require('./components/App/App');
16 |
17 | var _App2 = _interopRequireDefault(_App);
18 |
19 | var _Home = require('./components/Home/Home');
20 |
21 | var _Home2 = _interopRequireDefault(_Home);
22 |
23 | var _GraphiQL = require('./components/GraphiQL/GraphiQL');
24 |
25 | var _GraphiQL2 = _interopRequireDefault(_GraphiQL);
26 |
27 | var _apollo = require('../apollo');
28 |
29 | var _apollo2 = _interopRequireDefault(_apollo);
30 |
31 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
32 |
33 | _reactDom2.default.render(_react2.default.createElement(
34 | _reactApollo.ApolloProvider,
35 | { client: _apollo2.default },
36 | _react2.default.createElement(
37 | _reactRouter.Router,
38 | {
39 | history: _reactRouter.browserHistory,
40 | routes: _reactRouter.routes,
41 | render: (0, _reactRouter.applyRouterMiddleware)()
42 | },
43 | _react2.default.createElement(_reactRouter.Route, { path: '/', component: _App2.default }),
44 | _react2.default.createElement(_reactRouter.Route, { path: '/home', component: _Home2.default }),
45 | _react2.default.createElement(_reactRouter.Route, { path: '/graphiql', component: _GraphiQL2.default })
46 | )
47 | ), document.getElementById('root'));
--------------------------------------------------------------------------------
/lib/js/components/App/App.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _templateObject = _taggedTemplateLiteral(['\n query GetUser($id: ID!) {\n getUser(id: $id) {\n id\n username\n }\n }\n'], ['\n query GetUser($id: ID!) {\n getUser(id: $id) {\n id\n username\n }\n }\n']);
10 |
11 | var _react = require('react');
12 |
13 | var _react2 = _interopRequireDefault(_react);
14 |
15 | var _graphqlTag = require('graphql-tag');
16 |
17 | var _graphqlTag2 = _interopRequireDefault(_graphqlTag);
18 |
19 | var _reactRouter = require('react-router');
20 |
21 | var _apollo = require('../../../apollo');
22 |
23 | var _apollo2 = _interopRequireDefault(_apollo);
24 |
25 | var _Header = require('./Header');
26 |
27 | var _Header2 = _interopRequireDefault(_Header);
28 |
29 | var _Hero = require('./Hero');
30 |
31 | var _Hero2 = _interopRequireDefault(_Hero);
32 |
33 | var _Description = require('./Description');
34 |
35 | var _Description2 = _interopRequireDefault(_Description);
36 |
37 | var _Footer = require('./Footer');
38 |
39 | var _Footer2 = _interopRequireDefault(_Footer);
40 |
41 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
42 |
43 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
44 |
45 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
46 |
47 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
48 |
49 | function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
50 |
51 | var userQuery = (0, _graphqlTag2.default)(_templateObject);
52 |
53 | var App = function (_React$Component) {
54 | _inherits(App, _React$Component);
55 |
56 | function App(props) {
57 | _classCallCheck(this, App);
58 |
59 | var _this = _possibleConstructorReturn(this, (App.__proto__ || Object.getPrototypeOf(App)).call(this, props));
60 |
61 | _this.state = {
62 | loading: true
63 | };
64 | return _this;
65 | }
66 |
67 | _createClass(App, [{
68 | key: 'componentDidMount',
69 | value: function componentDidMount() {
70 | var token = localStorage.getItem('token');
71 | var user = JSON.parse(localStorage.getItem('user'));
72 | var userId = user ? user.id : null;
73 | if (token && userId) {
74 | // If we are logged in subscribe to the user and render the app.
75 | this.subscribeToUser(userId);
76 | } else {
77 | // We are not logged in so stop loading and render the landing page.
78 | this.setState({ // eslint-disable-line
79 | loading: false
80 | });
81 | }
82 | }
83 | }, {
84 | key: 'subscribeToUser',
85 | value: function subscribeToUser(id) {
86 | var that = this;
87 | var observable = _apollo2.default.watchQuery({
88 | query: userQuery,
89 | pollInterval: 60000,
90 | forceFetch: true,
91 | variables: {
92 | id: id
93 | }
94 | });
95 | var subscription = observable.subscribe({
96 | next: function next(result) {
97 | if (result && result.errors) {
98 | var unauthed = result.errors.reduce(function (acc, err) {
99 | return acc || err.status === 401;
100 | }, false);
101 | if (unauthed) {
102 | localStorage.clear();
103 | that.setState({
104 | user: result.data.getUser,
105 | loading: false
106 | });
107 | }
108 | } else {
109 | localStorage.setItem('currentUsername', result.data.getUser.username);
110 | that.setState({
111 | user: result.data.getUser,
112 | loading: false
113 | });
114 | _reactRouter.browserHistory.push('/home');
115 | }
116 | },
117 | error: function error(_error) {
118 | console.log('Error subscribing to user: ' + _error.toString());
119 | that.setState({
120 | loading: false
121 | });
122 | },
123 | // Network error, etc.
124 | complete: function complete() {
125 | // console.log(`Subscription complete`);
126 | }
127 | });
128 | this.setState({
129 | userSubscription: subscription
130 | });
131 | }
132 | }, {
133 | key: 'render',
134 | value: function render() {
135 | return _react2.default.createElement(
136 | 'div',
137 | null,
138 | _react2.default.createElement(_Header2.default, null),
139 | _react2.default.createElement(_Hero2.default, null),
140 | _react2.default.createElement(_Description2.default, null),
141 | _react2.default.createElement(_Footer2.default, null)
142 | );
143 | }
144 | }]);
145 |
146 | return App;
147 | }(_react2.default.Component);
148 |
149 | App.propTypes = {};
150 |
151 | exports.default = App;
--------------------------------------------------------------------------------
/lib/js/components/App/Description.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _react = require('react');
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | var _reactBootstrap = require('react-bootstrap');
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18 |
19 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
20 |
21 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
22 |
23 | var styles = {
24 | marketing: {
25 | margin: '40px 0',
26 | p: {
27 | marginTop: 28
28 | },
29 | h4: {
30 | marginTop: 28
31 | }
32 | }
33 | };
34 |
35 | var Description = function (_React$Component) {
36 | _inherits(Description, _React$Component);
37 |
38 | function Description() {
39 | _classCallCheck(this, Description);
40 |
41 | return _possibleConstructorReturn(this, (Description.__proto__ || Object.getPrototypeOf(Description)).apply(this, arguments));
42 | }
43 |
44 | _createClass(Description, [{
45 | key: 'render',
46 | // eslint-disable-line
47 | value: function render() {
48 | return _react2.default.createElement(
49 | _reactBootstrap.Row,
50 | { style: styles.marketing },
51 | _react2.default.createElement(
52 | _reactBootstrap.Col,
53 | { smOffset: 2, sm: 4 },
54 | _react2.default.createElement(
55 | 'h4',
56 | { style: styles.marketing.h4 },
57 | _react2.default.createElement(
58 | 'a',
59 | { target: '_blank', href: 'https://facebook.github.io/react/' },
60 | 'React.js Boilerplate'
61 | )
62 | ),
63 | _react2.default.createElement(
64 | 'p',
65 | { style: styles.marketing.p },
66 | 'This React.js boilerplate helps developers create modern, performant, and clean web apps with the help of Scaphold.io.'
67 | ),
68 | _react2.default.createElement(
69 | 'h4',
70 | { style: styles.marketing.h4 },
71 | _react2.default.createElement(
72 | 'a',
73 | { target: '_blank', href: 'http://dev.apollodata.com/react/' },
74 | 'React-Apollo'
75 | )
76 | ),
77 | _react2.default.createElement(
78 | 'p',
79 | { style: styles.marketing.p },
80 | 'Leverage the simplicity and power of Apollo Client and GraphQL to manage your application\'s data store.'
81 | )
82 | ),
83 | _react2.default.createElement(
84 | _reactBootstrap.Col,
85 | { sm: 4 },
86 | _react2.default.createElement(
87 | 'h4',
88 | { style: styles.marketing.h4 },
89 | _react2.default.createElement(
90 | 'a',
91 | { target: '_blank', href: 'https://react-bootstrap.github.io/' },
92 | 'React-Bootstrap'
93 | )
94 | ),
95 | _react2.default.createElement(
96 | 'p',
97 | { style: styles.marketing.p },
98 | 'Smoothe and creative components to fit the way you want your apps to be experienced.'
99 | ),
100 | _react2.default.createElement(
101 | 'h4',
102 | { style: styles.marketing.h4 },
103 | _react2.default.createElement(
104 | 'a',
105 | { target: '_blank', href: 'https://webpack.github.io/docs/list-of-tutorials.html' },
106 | 'Webpack'
107 | )
108 | ),
109 | _react2.default.createElement(
110 | 'p',
111 | { style: styles.marketing.p },
112 | 'Webpack is a module bundler that helps you serve your application in any environment with hot reloading.'
113 | )
114 | )
115 | );
116 | }
117 | }]);
118 |
119 | return Description;
120 | }(_react2.default.Component);
121 |
122 | exports.default = Description;
--------------------------------------------------------------------------------
/lib/js/components/App/Footer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _react = require('react');
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | var _reactFontawesome = require('react-fontawesome');
14 |
15 | var _reactFontawesome2 = _interopRequireDefault(_reactFontawesome);
16 |
17 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18 |
19 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20 |
21 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
22 |
23 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
24 |
25 | var styles = {
26 | footer: {
27 | textAlign: 'center',
28 | paddingTop: 20,
29 | color: '#777',
30 | borderTop: '1px, solid, #e5e5e5'
31 | }
32 | };
33 |
34 | var Footer = function (_React$Component) {
35 | _inherits(Footer, _React$Component);
36 |
37 | function Footer() {
38 | _classCallCheck(this, Footer);
39 |
40 | return _possibleConstructorReturn(this, (Footer.__proto__ || Object.getPrototypeOf(Footer)).apply(this, arguments));
41 | }
42 |
43 | _createClass(Footer, [{
44 | key: 'render',
45 | // eslint-disable-line
46 | value: function render() {
47 | return _react2.default.createElement(
48 | 'p',
49 | { style: styles.footer },
50 | 'Made with ',
51 | _react2.default.createElement(_reactFontawesome2.default, { name: 'heart' }),
52 | ' from the Scaphold Team'
53 | );
54 | }
55 | }]);
56 |
57 | return Footer;
58 | }(_react2.default.Component);
59 |
60 | exports.default = Footer;
--------------------------------------------------------------------------------
/lib/js/components/App/Header.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _react = require('react');
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | var _reactRouter = require('react-router');
14 |
15 | var _reactBootstrap = require('react-bootstrap');
16 |
17 | var _Login = require('./Login');
18 |
19 | var _Login2 = _interopRequireDefault(_Login);
20 |
21 | var _Register = require('./Register');
22 |
23 | var _Register2 = _interopRequireDefault(_Register);
24 |
25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26 |
27 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
28 |
29 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
30 |
31 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
32 |
33 | var Header = function (_React$Component) {
34 | _inherits(Header, _React$Component);
35 |
36 | function Header(props) {
37 | _classCallCheck(this, Header);
38 |
39 | var _this = _possibleConstructorReturn(this, (Header.__proto__ || Object.getPrototypeOf(Header)).call(this, props));
40 |
41 | _this.state = {
42 | showModal: false
43 | };
44 | return _this;
45 | }
46 |
47 | _createClass(Header, [{
48 | key: 'goToGraphiQL',
49 | value: function goToGraphiQL() {
50 | _reactRouter.browserHistory.push('/graphiql');
51 | }
52 | }, {
53 | key: 'goHome',
54 | value: function goHome() {
55 | _reactRouter.browserHistory.push('/');
56 | }
57 | }, {
58 | key: 'render',
59 | value: function render() {
60 | return _react2.default.createElement(
61 | _reactBootstrap.Navbar,
62 | { style: styles.navbar },
63 | _react2.default.createElement(
64 | _reactBootstrap.Navbar.Header,
65 | null,
66 | _react2.default.createElement(
67 | _reactBootstrap.Navbar.Brand,
68 | null,
69 | _react2.default.createElement(
70 | _reactRouter.Link,
71 | { to: '/' },
72 | 'Scaphold'
73 | )
74 | )
75 | ),
76 | _react2.default.createElement(
77 | _reactBootstrap.Nav,
78 | { pullRight: true },
79 | _react2.default.createElement(
80 | _reactBootstrap.NavItem,
81 | { onClick: this.goHome },
82 | 'Home'
83 | ),
84 | _react2.default.createElement(
85 | _reactBootstrap.NavItem,
86 | { onClick: this.goToGraphiQL },
87 | 'GraphiQL'
88 | ),
89 | _react2.default.createElement(_Login2.default, null),
90 | _react2.default.createElement(_Register2.default, null)
91 | )
92 | );
93 | }
94 | }]);
95 |
96 | return Header;
97 | }(_react2.default.Component);
98 |
99 | exports.default = Header;
100 |
101 |
102 | var styles = {
103 | navbar: {
104 | marginBottom: 0
105 | }
106 | };
--------------------------------------------------------------------------------
/lib/js/components/App/Hero.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _react = require('react');
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | var _reactBootstrap = require('react-bootstrap');
14 |
15 | var _reactFontawesome = require('react-fontawesome');
16 |
17 | var _reactFontawesome2 = _interopRequireDefault(_reactFontawesome);
18 |
19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20 |
21 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
22 |
23 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
24 |
25 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
26 |
27 | var Hero = function (_React$Component) {
28 | _inherits(Hero, _React$Component);
29 |
30 | function Hero() {
31 | _classCallCheck(this, Hero);
32 |
33 | return _possibleConstructorReturn(this, (Hero.__proto__ || Object.getPrototypeOf(Hero)).apply(this, arguments));
34 | }
35 |
36 | _createClass(Hero, [{
37 | key: 'render',
38 | value: function render() {
39 | return _react2.default.createElement(
40 | _reactBootstrap.Row,
41 | null,
42 | _react2.default.createElement(
43 | _reactBootstrap.Col,
44 | { smOffset: 2, sm: 8 },
45 | _react2.default.createElement(
46 | _reactBootstrap.Jumbotron,
47 | { style: styles.jumbotron },
48 | _react2.default.createElement(
49 | 'h1',
50 | null,
51 | 'Welcome!'
52 | ),
53 | _react2.default.createElement('br', null),
54 | _react2.default.createElement(
55 | 'p',
56 | null,
57 | 'Here you\'ll find ',
58 | _react2.default.createElement(
59 | 'a',
60 | { href: 'https://scaphold.io', target: '_blank', style: styles.scaphold },
61 | 'Scaphold.io'
62 | ),
63 | '\'s Boilerplate React-Apollo template \xA0',
64 | _react2.default.createElement(_reactFontawesome2.default, { name: 'smile-o' })
65 | ),
66 | _react2.default.createElement('br', null),
67 | _react2.default.createElement(
68 | 'p',
69 | null,
70 | _react2.default.createElement(
71 | _reactBootstrap.Button,
72 | { bsStyle: 'primary', bsSize: 'large', target: '_blank', href: 'https://scaphold.io' },
73 | 'Learn more ',
74 | _react2.default.createElement(_reactFontawesome2.default, { name: 'check' })
75 | ),
76 | _react2.default.createElement(
77 | _reactBootstrap.Button,
78 | { style: styles.slack, bsSize: 'large', target: '_blank', href: 'http://slack.scaphold.io' },
79 | 'Join our Slack ',
80 | _react2.default.createElement(_reactFontawesome2.default, { name: 'slack' })
81 | )
82 | )
83 | )
84 | )
85 | );
86 | }
87 | }]);
88 |
89 | return Hero;
90 | }(_react2.default.Component);
91 |
92 | exports.default = Hero;
93 |
94 |
95 | var styles = {
96 | jumbotron: {
97 | marginTop: 20,
98 | borderRadius: 10,
99 | textAlign: 'center'
100 | },
101 | scaphold: {
102 | color: '#1DAAA0'
103 | },
104 | slack: {
105 | color: 'white',
106 | backgroundColor: '#1DAAA0'
107 | }
108 | };
--------------------------------------------------------------------------------
/lib/js/components/App/Login.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _templateObject = _taggedTemplateLiteral(['\n mutation LoginUserMutation($data: LoginUserInput!) {\n loginUser(input: $data) {\n token\n user {\n id\n username\n }\n }\n }\n'], ['\n mutation LoginUserMutation($data: LoginUserInput!) {\n loginUser(input: $data) {\n token\n user {\n id\n username\n }\n }\n }\n']);
10 |
11 | var _react = require('react');
12 |
13 | var _react2 = _interopRequireDefault(_react);
14 |
15 | var _reactApollo = require('react-apollo');
16 |
17 | var _graphqlTag = require('graphql-tag');
18 |
19 | var _graphqlTag2 = _interopRequireDefault(_graphqlTag);
20 |
21 | var _reactRouter = require('react-router');
22 |
23 | var _reactBootstrap = require('react-bootstrap');
24 |
25 | var _config = require('./../../../config');
26 |
27 | var _config2 = _interopRequireDefault(_config);
28 |
29 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
30 |
31 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
32 |
33 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
34 |
35 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
36 |
37 | function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
38 |
39 | var LoginUserMutation = (0, _graphqlTag2.default)(_templateObject);
40 |
41 | var Login = function (_React$Component) {
42 | _inherits(Login, _React$Component);
43 |
44 | function Login(props) {
45 | _classCallCheck(this, Login);
46 |
47 | var _this = _possibleConstructorReturn(this, (Login.__proto__ || Object.getPrototypeOf(Login)).call(this, props));
48 |
49 | _this.state = {
50 | showModal: false,
51 | loginEmail: '',
52 | loginPassword: '',
53 | errors: []
54 | };
55 | _this.close = _this.close.bind(_this);
56 | _this.open = _this.open.bind(_this);
57 | _this._handleLoginEmailChange = _this._handleLoginEmailChange.bind(_this);
58 | _this._handleLoginPasswordChange = _this._handleLoginPasswordChange.bind(_this);
59 | _this.validateInput = _this.validateInput.bind(_this);
60 | _this.loginUser = _this.loginUser.bind(_this);
61 | return _this;
62 | }
63 |
64 | _createClass(Login, [{
65 | key: 'close',
66 | value: function close() {
67 | this.setState({ showModal: false });
68 | }
69 | }, {
70 | key: 'open',
71 | value: function open() {
72 | this.setState({ showModal: true });
73 | }
74 | }, {
75 | key: '_handleLoginEmailChange',
76 | value: function _handleLoginEmailChange(e) {
77 | this.setState({
78 | loginEmail: e.target.value
79 | });
80 | }
81 | }, {
82 | key: '_handleLoginPasswordChange',
83 | value: function _handleLoginPasswordChange(e) {
84 | this.setState({
85 | loginPassword: e.target.value
86 | });
87 | }
88 | }, {
89 | key: 'validateInput',
90 | value: function validateInput() {
91 | return this.state.loginEmail && this.state.loginEmail.length && this.state.loginPassword && this.state.loginPassword.length;
92 | }
93 | }, {
94 | key: 'loginUser',
95 | value: function loginUser() {
96 | var _this2 = this;
97 |
98 | if (this.validateInput()) {
99 | this.props.login({
100 | username: this.state.loginEmail,
101 | password: this.state.loginPassword
102 | }).then(function (_ref) {
103 | var data = _ref.data;
104 |
105 | if (!data.errors) {
106 | localStorage.setItem('token', data.loginUser.token);
107 | localStorage.setItem('user', JSON.stringify(data.loginUser.user));
108 | _this2.setState({ errors: [] });
109 | _reactRouter.browserHistory.push('/home');
110 | } else {
111 | _this2.setState({ errors: data.errors });
112 | }
113 | }).catch(function (errors) {
114 | _this2.setState({ errors: errors.graphQLErrors });
115 | });
116 | } else {
117 | this.setState({
118 | errors: [{
119 | message: 'Username or password was not filled out. Please fill out the required fields.'
120 | }]
121 | });
122 | }
123 | }
124 | }, {
125 | key: 'render',
126 | value: function render() {
127 | return _react2.default.createElement(
128 | _reactBootstrap.NavItem,
129 | { onClick: this.open },
130 | 'Login',
131 | _react2.default.createElement(
132 | _reactBootstrap.Modal,
133 | { show: this.state.showModal, onHide: this.close },
134 | _react2.default.createElement(
135 | _reactBootstrap.Modal.Header,
136 | { closeButton: true },
137 | _react2.default.createElement(
138 | _reactBootstrap.Modal.Title,
139 | null,
140 | 'Login Here!'
141 | )
142 | ),
143 | _react2.default.createElement(
144 | _reactBootstrap.Modal.Body,
145 | null,
146 | _react2.default.createElement(
147 | 'div',
148 | { style: styles.errors },
149 | this.state.errors.map(function (err, i) {
150 | return _react2.default.createElement(
151 | _reactBootstrap.Alert,
152 | { key: i, bsStyle: 'danger' },
153 | err.message
154 | );
155 | })
156 | ),
157 | _react2.default.createElement(
158 | _reactBootstrap.Form,
159 | { horizontal: true },
160 | _react2.default.createElement(
161 | _reactBootstrap.FormGroup,
162 | { controlId: 'formLoginEmail' },
163 | _react2.default.createElement(
164 | _reactBootstrap.Col,
165 | { componentClass: _reactBootstrap.ControlLabel, smOffset: 1, sm: 2 },
166 | 'Email'
167 | ),
168 | _react2.default.createElement(
169 | _reactBootstrap.Col,
170 | { sm: 8 },
171 | _react2.default.createElement(_reactBootstrap.FormControl, { type: 'email', placeholder: 'Email', onChange: this._handleLoginEmailChange })
172 | )
173 | ),
174 | _react2.default.createElement(
175 | _reactBootstrap.FormGroup,
176 | { controlId: 'formLoginPassword' },
177 | _react2.default.createElement(
178 | _reactBootstrap.Col,
179 | { componentClass: _reactBootstrap.ControlLabel, smOffset: 1, sm: 2 },
180 | 'Password'
181 | ),
182 | _react2.default.createElement(
183 | _reactBootstrap.Col,
184 | { sm: 8 },
185 | _react2.default.createElement(_reactBootstrap.FormControl, { type: 'password', placeholder: 'Password', onChange: this._handleLoginPasswordChange })
186 | )
187 | )
188 | )
189 | ),
190 | _react2.default.createElement(
191 | _reactBootstrap.Modal.Footer,
192 | null,
193 | _react2.default.createElement(
194 | _reactBootstrap.Button,
195 | { bsStyle: 'primary', type: 'submit', onClick: this.loginUser },
196 | 'Login'
197 | ),
198 | _react2.default.createElement(
199 | _reactBootstrap.Button,
200 | { onClick: this.close },
201 | 'Close'
202 | )
203 | )
204 | )
205 | );
206 | }
207 | }]);
208 |
209 | return Login;
210 | }(_react2.default.Component);
211 |
212 | var styles = {
213 | errors: {
214 | textAlign: 'left',
215 | color: 'red'
216 | }
217 | };
218 |
219 | var LoginWithData = (0, _reactApollo.graphql)(LoginUserMutation, {
220 | props: function props(_ref2) {
221 | var mutate = _ref2.mutate;
222 | return {
223 | login: function login(data) {
224 | return mutate({
225 | variables: {
226 | data: data
227 | }
228 | });
229 | }
230 | };
231 | }
232 | })(Login);
233 | exports.default = LoginWithData;
--------------------------------------------------------------------------------
/lib/js/components/App/Register.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _templateObject = _taggedTemplateLiteral(['\n mutation CreateUserMutation($data: CreateUserInput!) {\n createUser(input: $data) {\n token\n changedUser {\n id\n username\n }\n }\n }\n'], ['\n mutation CreateUserMutation($data: CreateUserInput!) {\n createUser(input: $data) {\n token\n changedUser {\n id\n username\n }\n }\n }\n']);
10 |
11 | var _react = require('react');
12 |
13 | var _react2 = _interopRequireDefault(_react);
14 |
15 | var _reactApollo = require('react-apollo');
16 |
17 | var _graphqlTag = require('graphql-tag');
18 |
19 | var _graphqlTag2 = _interopRequireDefault(_graphqlTag);
20 |
21 | var _reactRouter = require('react-router');
22 |
23 | var _reactBootstrap = require('react-bootstrap');
24 |
25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26 |
27 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
28 |
29 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
30 |
31 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
32 |
33 | function _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
34 |
35 | var CreateUserMutation = (0, _graphqlTag2.default)(_templateObject);
36 |
37 | var Register = function (_React$Component) {
38 | _inherits(Register, _React$Component);
39 |
40 | function Register(props) {
41 | _classCallCheck(this, Register);
42 |
43 | var _this = _possibleConstructorReturn(this, (Register.__proto__ || Object.getPrototypeOf(Register)).call(this, props));
44 |
45 | _this.state = {
46 | showModal: false,
47 | registerEmail: '',
48 | registerPassword: '',
49 | errors: []
50 | };
51 |
52 | _this.close = _this.close.bind(_this);
53 | _this.open = _this.open.bind(_this);
54 | _this._handleRegisterEmailChange = _this._handleRegisterEmailChange.bind(_this);
55 | _this._handleRegisterPasswordChange = _this._handleRegisterPasswordChange.bind(_this);
56 | _this.validateInput = _this.validateInput.bind(_this);
57 | _this.registerUser = _this.registerUser.bind(_this);
58 | return _this;
59 | }
60 |
61 | _createClass(Register, [{
62 | key: 'close',
63 | value: function close() {
64 | this.setState({ showModal: false });
65 | }
66 | }, {
67 | key: 'open',
68 | value: function open() {
69 | this.setState({ showModal: true });
70 | }
71 | }, {
72 | key: 'validateInput',
73 | value: function validateInput() {
74 | return this.state.registerEmail && this.state.registerEmail.length && this.state.registerPassword && this.state.registerPassword.length;
75 | }
76 | }, {
77 | key: 'registerUser',
78 | value: function registerUser() {
79 | var _this2 = this;
80 |
81 | if (this.validateInput()) {
82 | this.props.register({
83 | username: this.state.registerEmail,
84 | password: this.state.registerPassword
85 | }).then(function (_ref) {
86 | var data = _ref.data;
87 |
88 | if (!data.errors) {
89 | localStorage.setItem('token', data.createUser.token);
90 | localStorage.setItem('user', JSON.stringify(data.createUser.changedUser));
91 | _this2.setState({ errors: [] });
92 | _reactRouter.browserHistory.push('/home');
93 | } else {
94 | _this2.setState({ errors: data.errors });
95 | }
96 | }).catch(function (errors) {
97 | _this2.setState({ errors: errors.graphQLErrors });
98 | });
99 | } else {
100 | this.setState({
101 | errors: [{
102 | message: 'Username or password was not filled out. Please fill out the required fields.'
103 | }]
104 | });
105 | }
106 | }
107 | }, {
108 | key: '_handleRegisterEmailChange',
109 | value: function _handleRegisterEmailChange(e) {
110 | this.setState({
111 | registerEmail: e.target.value
112 | });
113 | }
114 | }, {
115 | key: '_handleRegisterPasswordChange',
116 | value: function _handleRegisterPasswordChange(e) {
117 | this.setState({
118 | registerPassword: e.target.value
119 | });
120 | }
121 | }, {
122 | key: 'render',
123 | value: function render() {
124 | return _react2.default.createElement(
125 | _reactBootstrap.NavItem,
126 | { onClick: this.open },
127 | 'Register',
128 | _react2.default.createElement(
129 | _reactBootstrap.Modal,
130 | { show: this.state.showModal, onHide: this.close },
131 | _react2.default.createElement(
132 | _reactBootstrap.Modal.Header,
133 | { closeButton: true },
134 | _react2.default.createElement(
135 | _reactBootstrap.Modal.Title,
136 | null,
137 | 'Register Here!'
138 | )
139 | ),
140 | _react2.default.createElement(
141 | _reactBootstrap.Modal.Body,
142 | null,
143 | _react2.default.createElement(
144 | 'div',
145 | { style: styles.errors },
146 | this.state.errors.map(function (err, i) {
147 | return _react2.default.createElement(
148 | _reactBootstrap.Alert,
149 | { key: i, bsStyle: 'danger' },
150 | err.message
151 | );
152 | })
153 | ),
154 | _react2.default.createElement(
155 | _reactBootstrap.Form,
156 | { horizontal: true },
157 | _react2.default.createElement(
158 | _reactBootstrap.Row,
159 | null,
160 | _react2.default.createElement(
161 | _reactBootstrap.FormGroup,
162 | { controlId: 'formRegisterEmail' },
163 | _react2.default.createElement(
164 | _reactBootstrap.Col,
165 | { componentClass: _reactBootstrap.ControlLabel, smOffset: 1, sm: 2 },
166 | 'Email'
167 | ),
168 | _react2.default.createElement(
169 | _reactBootstrap.Col,
170 | { sm: 8 },
171 | _react2.default.createElement(_reactBootstrap.FormControl, { type: 'email', placeholder: 'Email', onChange: this._handleRegisterEmailChange })
172 | )
173 | ),
174 | _react2.default.createElement(
175 | _reactBootstrap.FormGroup,
176 | { controlId: 'formRegisterPassword' },
177 | _react2.default.createElement(
178 | _reactBootstrap.Col,
179 | { componentClass: _reactBootstrap.ControlLabel, smOffset: 1, sm: 2 },
180 | 'Password'
181 | ),
182 | _react2.default.createElement(
183 | _reactBootstrap.Col,
184 | { sm: 8 },
185 | _react2.default.createElement(_reactBootstrap.FormControl, { type: 'password', placeholder: 'Password', onChange: this._handleRegisterPasswordChange })
186 | )
187 | )
188 | )
189 | )
190 | ),
191 | _react2.default.createElement(
192 | _reactBootstrap.Modal.Footer,
193 | null,
194 | _react2.default.createElement(
195 | _reactBootstrap.Button,
196 | { bsStyle: 'primary', type: 'submit', onClick: this.registerUser },
197 | 'Register'
198 | ),
199 | _react2.default.createElement(
200 | _reactBootstrap.Button,
201 | { onClick: this.close },
202 | 'Close'
203 | )
204 | )
205 | )
206 | );
207 | }
208 | }]);
209 |
210 | return Register;
211 | }(_react2.default.Component);
212 |
213 | var styles = {
214 | errors: {
215 | textAlign: 'left',
216 | color: 'red'
217 | }
218 | };
219 |
220 | var RegisterWithData = (0, _reactApollo.graphql)(CreateUserMutation, {
221 | props: function props(_ref2) {
222 | var mutate = _ref2.mutate;
223 | return {
224 | register: function register(data) {
225 | return mutate({
226 | variables: {
227 | data: data
228 | }
229 | });
230 | }
231 | };
232 | }
233 | })(Register);
234 | exports.default = RegisterWithData;
--------------------------------------------------------------------------------
/lib/js/components/GraphiQL/GraphiQL.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _react = require('react');
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | var _graphiql = require('graphiql');
14 |
15 | var _graphiql2 = _interopRequireDefault(_graphiql);
16 |
17 | var _isomorphicFetch = require('isomorphic-fetch');
18 |
19 | var _isomorphicFetch2 = _interopRequireDefault(_isomorphicFetch);
20 |
21 | var _config = require('./../../../config');
22 |
23 | var _config2 = _interopRequireDefault(_config);
24 |
25 | var _Header = require('./../App/Header');
26 |
27 | var _Header2 = _interopRequireDefault(_Header);
28 |
29 | var _Header3 = require('./../Home/Header');
30 |
31 | var _Header4 = _interopRequireDefault(_Header3);
32 |
33 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
34 |
35 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
36 |
37 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
38 |
39 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
40 |
41 | function graphQLFetcher(graphQLParams) {
42 | return (0, _isomorphicFetch2.default)(_config2.default.scapholdUrl, {
43 | method: 'post',
44 | headers: {
45 | 'Content-Type': 'application/json',
46 | Authorization: localStorage.token ? 'Bearer ' + localStorage.token : ''
47 | },
48 | body: JSON.stringify(graphQLParams)
49 | }).then(function (response) {
50 | return response.json();
51 | });
52 | }
53 |
54 | var GraphiQLModule = function (_React$Component) {
55 | _inherits(GraphiQLModule, _React$Component);
56 |
57 | function GraphiQLModule() {
58 | _classCallCheck(this, GraphiQLModule);
59 |
60 | return _possibleConstructorReturn(this, (GraphiQLModule.__proto__ || Object.getPrototypeOf(GraphiQLModule)).apply(this, arguments));
61 | }
62 |
63 | _createClass(GraphiQLModule, [{
64 | key: 'render',
65 | value: function render() {
66 | var header = void 0;
67 | if (!localStorage.token) {
68 | header = _react2.default.createElement(_Header2.default, null);
69 | } else {
70 | header = _react2.default.createElement(_Header4.default, null);
71 | }
72 |
73 | return _react2.default.createElement(
74 | 'span',
75 | null,
76 | header,
77 | _react2.default.createElement(_graphiql2.default, { fetcher: graphQLFetcher })
78 | );
79 | }
80 | }]);
81 |
82 | return GraphiQLModule;
83 | }(_react2.default.Component);
84 |
85 | exports.default = GraphiQLModule;
--------------------------------------------------------------------------------
/lib/js/components/Home/Body.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _react = require('react');
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | var _reactBootstrap = require('react-bootstrap');
14 |
15 | var _Description = require('../App/Description');
16 |
17 | var _Description2 = _interopRequireDefault(_Description);
18 |
19 | var _reactFontawesome = require('react-fontawesome');
20 |
21 | var _reactFontawesome2 = _interopRequireDefault(_reactFontawesome);
22 |
23 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24 |
25 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
26 |
27 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
28 |
29 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
30 |
31 | var Body = function (_React$Component) {
32 | _inherits(Body, _React$Component);
33 |
34 | function Body() {
35 | _classCallCheck(this, Body);
36 |
37 | return _possibleConstructorReturn(this, (Body.__proto__ || Object.getPrototypeOf(Body)).apply(this, arguments));
38 | }
39 |
40 | _createClass(Body, [{
41 | key: 'render',
42 | value: function render() {
43 | var user = JSON.parse(localStorage.getItem('user'));
44 | var loggedInUser = user ? user.username : '';
45 |
46 | return _react2.default.createElement(
47 | 'div',
48 | null,
49 | _react2.default.createElement(
50 | _reactBootstrap.Row,
51 | { style: styles.heading },
52 | 'Welcome, you\'ve successfully logged in to ',
53 | _react2.default.createElement(
54 | 'a',
55 | { href: 'https://scaphold.io', target: '_blank', style: styles.scaphold },
56 | 'Scaphold'
57 | ),
58 | '\'s React Apollo Starter Kit!'
59 | ),
60 | _react2.default.createElement(
61 | _reactBootstrap.Row,
62 | { style: styles.subheading },
63 | _react2.default.createElement(
64 | _reactBootstrap.Col,
65 | { smOffset: 3, sm: 6 },
66 | loggedInUser ? _react2.default.createElement(
67 | 'div',
68 | { style: styles.subheading.section },
69 | 'Username: ',
70 | _react2.default.createElement(
71 | 'b',
72 | null,
73 | loggedInUser
74 | )
75 | ) : '',
76 | _react2.default.createElement(
77 | 'div',
78 | { style: styles.subheading.section },
79 | 'Feel free to poke around and check out the other functionality that this starter kit provides. We\'ve put together a couple tools for you to get this starter kit rolling.'
80 | ),
81 | _react2.default.createElement(
82 | 'div',
83 | { style: styles.subheading.section },
84 | 'So by all means, modify the code, break it, and learn about the same awesome technology that Facebook is built on.'
85 | ),
86 | _react2.default.createElement(
87 | 'div',
88 | { style: styles.subheading.section },
89 | _react2.default.createElement(
90 | _reactBootstrap.Button,
91 | { bsStyle: 'primary', bsSize: 'large', target: '_blank', href: 'https://scaphold.io' },
92 | 'Learn more ',
93 | _react2.default.createElement(_reactFontawesome2.default, { name: 'check' })
94 | ),
95 | _react2.default.createElement(
96 | _reactBootstrap.Button,
97 | { style: styles.slack, bsSize: 'large', target: '_blank', href: 'http://slack.scaphold.io' },
98 | 'Join our Slack ',
99 | _react2.default.createElement(_reactFontawesome2.default, { name: 'slack' })
100 | )
101 | )
102 | )
103 | ),
104 | _react2.default.createElement(_Description2.default, null)
105 | );
106 | }
107 | }]);
108 |
109 | return Body;
110 | }(_react2.default.Component);
111 |
112 | var styles = {
113 | heading: {
114 | padding: '100px 0 50px 0',
115 | fontSize: '25px',
116 | textAlign: 'center'
117 | },
118 | subheading: {
119 | padding: '0 0 50px 0',
120 | fontSize: '18px',
121 | textAlign: 'center',
122 | section: {
123 | padding: '25px'
124 | }
125 | },
126 | scaphold: {
127 | color: '#1DAAA0'
128 | },
129 | slack: {
130 | color: 'white',
131 | backgroundColor: '#1DAAA0'
132 | }
133 | };
134 |
135 | exports.default = Body;
--------------------------------------------------------------------------------
/lib/js/components/Home/Header.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _react = require('react');
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | var _reactApollo = require('react-apollo');
14 |
15 | var _graphqlTag = require('graphql-tag');
16 |
17 | var _graphqlTag2 = _interopRequireDefault(_graphqlTag);
18 |
19 | var _reactRouter = require('react-router');
20 |
21 | var _reactBootstrap = require('react-bootstrap');
22 |
23 | var _Logout = require('./Logout');
24 |
25 | var _Logout2 = _interopRequireDefault(_Logout);
26 |
27 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
28 |
29 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
30 |
31 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
32 |
33 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
34 |
35 | var Header = function (_React$Component) {
36 | _inherits(Header, _React$Component);
37 |
38 | function Header(props) {
39 | _classCallCheck(this, Header);
40 |
41 | var _this = _possibleConstructorReturn(this, (Header.__proto__ || Object.getPrototypeOf(Header)).call(this, props));
42 |
43 | _this.goToGraphiQL = _this.goToGraphiQL.bind(_this);
44 | _this.goHome = _this.goHome.bind(_this);
45 | return _this;
46 | }
47 |
48 | _createClass(Header, [{
49 | key: 'goToGraphiQL',
50 | value: function goToGraphiQL() {
51 | _reactRouter.browserHistory.push('/graphiql');
52 | }
53 | }, {
54 | key: 'goHome',
55 | value: function goHome() {
56 | _reactRouter.browserHistory.push('/home');
57 | }
58 | }, {
59 | key: 'render',
60 | value: function render() {
61 | var user = JSON.parse(localStorage.getItem('user'));
62 | var loggedInUser = user ? user.username : '';
63 |
64 | return _react2.default.createElement(
65 | _reactBootstrap.Navbar,
66 | { style: styles.navbar },
67 | _react2.default.createElement(
68 | _reactBootstrap.Navbar.Header,
69 | null,
70 | _react2.default.createElement(
71 | _reactBootstrap.Navbar.Brand,
72 | null,
73 | _react2.default.createElement(
74 | _reactRouter.Link,
75 | { to: '/home' },
76 | 'Scaphold'
77 | )
78 | )
79 | ),
80 | _react2.default.createElement(
81 | _reactBootstrap.Nav,
82 | { pullRight: true },
83 | _react2.default.createElement(
84 | _reactBootstrap.NavItem,
85 | { onClick: this.goHome },
86 | 'Home'
87 | ),
88 | _react2.default.createElement(
89 | _reactBootstrap.NavItem,
90 | { onClick: this.goToGraphiQL },
91 | 'GraphiQL'
92 | ),
93 | _react2.default.createElement(
94 | _reactBootstrap.NavItem,
95 | null,
96 | loggedInUser
97 | ),
98 | _react2.default.createElement(_Logout2.default, null)
99 | )
100 | );
101 | }
102 | }]);
103 |
104 | return Header;
105 | }(_react2.default.Component);
106 |
107 | var styles = {
108 | navbar: {
109 | marginBottom: 0
110 | }
111 | };
112 |
113 | exports.default = Header;
--------------------------------------------------------------------------------
/lib/js/components/Home/Home.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _react = require('react');
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | var _reactBootstrap = require('react-bootstrap');
14 |
15 | var _reactRouter = require('react-router');
16 |
17 | var _Header = require('./Header');
18 |
19 | var _Header2 = _interopRequireDefault(_Header);
20 |
21 | var _Body = require('./Body');
22 |
23 | var _Body2 = _interopRequireDefault(_Body);
24 |
25 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26 |
27 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
28 |
29 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
30 |
31 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
32 |
33 | var Home = function (_React$Component) {
34 | _inherits(Home, _React$Component);
35 |
36 | function Home() {
37 | _classCallCheck(this, Home);
38 |
39 | return _possibleConstructorReturn(this, (Home.__proto__ || Object.getPrototypeOf(Home)).apply(this, arguments));
40 | }
41 |
42 | _createClass(Home, [{
43 | key: 'render',
44 | value: function render() {
45 | if (!localStorage.token) {
46 | _reactRouter.browserHistory.push('/');
47 | }
48 |
49 | return _react2.default.createElement(
50 | 'div',
51 | null,
52 | _react2.default.createElement(_Header2.default, null),
53 | _react2.default.createElement(_Body2.default, null)
54 | );
55 | }
56 | }]);
57 |
58 | return Home;
59 | }(_react2.default.Component);
60 |
61 | exports.default = Home;
--------------------------------------------------------------------------------
/lib/js/components/Home/Logout.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _react = require('react');
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | var _reactRouter = require('react-router');
14 |
15 | var _reactBootstrap = require('react-bootstrap');
16 |
17 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18 |
19 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20 |
21 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
22 |
23 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
24 |
25 | var Logout = function (_React$Component) {
26 | _inherits(Logout, _React$Component);
27 |
28 | function Logout(props) {
29 | _classCallCheck(this, Logout);
30 |
31 | var _this = _possibleConstructorReturn(this, (Logout.__proto__ || Object.getPrototypeOf(Logout)).call(this, props));
32 |
33 | _this.logoutUser = _this.logoutUser.bind(_this);
34 | return _this;
35 | }
36 |
37 | _createClass(Logout, [{
38 | key: 'logoutUser',
39 | value: function logoutUser() {
40 | localStorage.clear();
41 | _reactRouter.browserHistory.push('/');
42 | }
43 | }, {
44 | key: 'render',
45 | value: function render() {
46 | return _react2.default.createElement(
47 | _reactBootstrap.NavItem,
48 | { onClick: this.logoutUser },
49 | 'Logout'
50 | );
51 | }
52 | }]);
53 |
54 | return Logout;
55 | }(_react2.default.Component);
56 |
57 | exports.default = Logout;
--------------------------------------------------------------------------------
/lib/server.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var fs = require('fs');
4 | var path = require('path');
5 | var webpack = require('webpack'); // eslint-disable-line
6 | var WebpackDevServer = require('webpack-dev-server'); // eslint-disable-line
7 | var config = require('./config');
8 |
9 | var APP_PORT = 3001;
10 |
11 | // Production version
12 | var compiler = webpack({
13 | entry: path.join(process.cwd(), 'lib', 'js', 'app.js'),
14 | module: {
15 | loaders: [{
16 | exclude: /node_modules/,
17 | // loader: 'babel-loader',
18 | test: /\.js$/
19 | }]
20 | },
21 | output: {
22 | path: path.join(process.cwd(), 'lib'), // sets our output directory to lib/
23 | filename: 'app.js', // sets our output filename to server.js
24 | publicPath: '/js/'
25 | }
26 | });
27 |
28 | var app = void 0;
29 | if (process.env.NODE_ENV !== 'production') {
30 | compiler = webpack({
31 | entry: path.join(process.cwd(), 'src', 'js', 'app.js'),
32 | module: {
33 | loaders: [{
34 | exclude: /node_modules/,
35 | loader: 'babel-loader',
36 | test: /\.js$/
37 | }]
38 | },
39 | output: {
40 | path: path.join(process.cwd(), 'src'), // sets our output directory to lib/
41 | filename: 'app.js', // sets our output filename to server.js
42 | publicPath: '/'
43 | }
44 | });
45 |
46 | app = new WebpackDevServer(compiler, {
47 | hot: true,
48 | contentBase: 'src/',
49 | publicPath: '/',
50 | proxy: { '/graphql': config.scapholdUrl },
51 | stats: {
52 | colors: true
53 | }
54 | });
55 | } else {
56 | app = new WebpackDevServer(compiler, {
57 | hot: false,
58 | contentBase: 'src/',
59 | publicPath: '/',
60 | proxy: { '/graphql': config.scapholdUrl },
61 | stats: {
62 | colors: false
63 | }
64 | });
65 | }
66 |
67 | // Serve static resources
68 | app.use('*', function (req, res) {
69 | fs.readFile(path.join(compiler.outputPath, 'index.html'), function (err, file) {
70 | if (err) {
71 | res.sendStatus(404);
72 | } else {
73 | res.send(file.toString());
74 | }
75 | });
76 | });
77 |
78 | app.listen(APP_PORT, function () {
79 | console.log('App is now running on http://localhost:' + APP_PORT);
80 | });
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-apollo-starter-kit",
3 | "description": "Scaphold.io's Starter Kit React and Apollo",
4 | "repository": "scaphold-io/react-apollo-starter-kit",
5 | "version": "0.1.0",
6 | "scripts": {
7 | "start": "babel-node ./src/server.js",
8 | "start:prod": "NODE_ENV=production node ./lib/server.js",
9 | "wp": "NODE_ENV=production webpack --config webpack/webpack.config.js --progress --color -p --display-error-details --verbose",
10 | "build": "cp src/index.html lib/ && babel src --out-dir lib --sourceRoot src",
11 | "buildw": "cp src/index.html lib/ && babel src --out-dir lib -w --sourceRoot src",
12 | "deploy": "npm run build && npm run wp"
13 | },
14 | "dependencies": {
15 | "apollo-client": "^0.9.0",
16 | "babel-polyfill": "6.7.4",
17 | "babel-preset-stage-0": "6.5.0",
18 | "babel-relay-plugin": "0.8.1",
19 | "classnames": "2.2.4",
20 | "express": "^4.13.4",
21 | "graphiql": "^0.9.3",
22 | "graphql": "^0.9.1",
23 | "graphql-tag": "^1.2.4",
24 | "isomorphic-fetch": "^2.2.1",
25 | "react": "^15.4.2",
26 | "react-apollo": "^0.12.0",
27 | "react-bootstrap": "^0.30.2",
28 | "react-dom": "^15.4.2",
29 | "react-fontawesome": "^1.1.0",
30 | "react-router": "^2.8.1",
31 | "react-router-scroll": "^0.3.2"
32 | },
33 | "devDependencies": {
34 | "babel-cli": "6.7.7",
35 | "babel-core": "^6.23.1",
36 | "babel-eslint": "^7.1.1",
37 | "babel-loader": "^6.3.2",
38 | "babel-preset-es2015": "^6.22.0",
39 | "babel-preset-react": "^6.5.0",
40 | "copy-webpack-plugin": "^4.0.1",
41 | "eslint": "^3.16.1",
42 | "eslint-config-airbnb": "^14.1.0",
43 | "eslint-plugin-flowtype": "^2.30.0",
44 | "eslint-plugin-import": "^2.2.0",
45 | "eslint-plugin-jsx-a11y": "^4.0.0",
46 | "eslint-plugin-react": "^6.10.0",
47 | "extract-text-webpack-plugin": "^1.0.1",
48 | "html-webpack-plugin": "^2.28.0",
49 | "static-site-generator-webpack-plugin": "^2.1.0",
50 | "webpack": "^2.2.1",
51 | "webpack-dev-server": "^2.4.1"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/apollo.js:
--------------------------------------------------------------------------------
1 | import ApolloClient, { createNetworkInterface } from 'apollo-client';
2 | import config from './config';
3 |
4 | const networkInterface = createNetworkInterface({
5 | uri: config.scapholdUrl,
6 | });
7 | networkInterface.use([{
8 | applyMiddleware(req, next) {
9 | if (!req.options.headers) {
10 | req.options.headers = {}; // Create the header object if needed.
11 | }
12 | if (localStorage.getItem('token')) {
13 | req.options.headers.Authorization = `Bearer ${localStorage.getItem('token')}`;
14 | }
15 | next();
16 | },
17 | }]);
18 |
19 | const client = new ApolloClient({
20 | networkInterface,
21 | });
22 |
23 | export default client;
24 |
--------------------------------------------------------------------------------
/src/config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Modify the config Scaphold URL to point to your specific app.
3 | * Find the URL at the top of the page on Scaphold.io once you've created an app.
4 | * Yup. It's that easy.
5 | */
6 |
7 | const config = {
8 | scapholdUrl: 'https://us-west-2.api.scaphold.io/graphql/react-apollo-starter-kit',
9 | };
10 |
11 | module.exports = config;
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | React-Apollo Starter Kit for Scaphold.io
10 |
11 |
16 |
17 |
18 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/js/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import { applyRouterMiddleware, Router, Route, routes, browserHistory } from 'react-router';
4 | import { ApolloProvider } from 'react-apollo';
5 | import App from './components/App/App';
6 | import Home from './components/Home/Home';
7 | import GraphiQLModule from './components/GraphiQL/GraphiQL';
8 | import client from '../apollo';
9 |
10 | ReactDOM.render(
11 |
12 |
19 |
20 |
21 |
22 |
23 | ,
24 | document.getElementById('root'), // eslint-disable-line
25 | );
26 |
--------------------------------------------------------------------------------
/src/js/components/App/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import gql from 'graphql-tag';
3 | import { browserHistory } from 'react-router';
4 | import client from '../../../apollo';
5 | import Header from './Header';
6 | import Hero from './Hero';
7 | import Description from './Description';
8 | import Footer from './Footer';
9 |
10 | const userQuery = gql`
11 | query GetUser($id: ID!) {
12 | getUser(id: $id) {
13 | id
14 | username
15 | }
16 | }
17 | `;
18 |
19 | class App extends React.Component {
20 | constructor(props) {
21 | super(props);
22 | this.state = {
23 | loading: true,
24 | };
25 | }
26 |
27 | componentDidMount() {
28 | const token = localStorage.getItem('token');
29 | const user = JSON.parse(localStorage.getItem('user'));
30 | const userId = user ? user.id : null;
31 | if (token && userId) {
32 | // If we are logged in subscribe to the user and render the app.
33 | this.subscribeToUser(userId);
34 | } else {
35 | // We are not logged in so stop loading and render the landing page.
36 | this.setState({ // eslint-disable-line
37 | loading: false,
38 | });
39 | }
40 | }
41 |
42 | subscribeToUser(id) {
43 | const that = this;
44 | const observable = client.watchQuery({
45 | query: userQuery,
46 | pollInterval: 60000,
47 | forceFetch: true,
48 | variables: {
49 | id,
50 | },
51 | });
52 | const subscription = observable.subscribe({
53 | next(result) {
54 | if (result && result.errors) {
55 | const unauthed = result.errors.reduce((acc, err) => (
56 | acc || err.status === 401
57 | ), false);
58 | if (unauthed) {
59 | localStorage.clear();
60 | that.setState({
61 | user: result.data.getUser,
62 | loading: false,
63 | });
64 | }
65 | } else {
66 | localStorage.setItem('currentUsername', result.data.getUser.username);
67 | that.setState({
68 | user: result.data.getUser,
69 | loading: false,
70 | });
71 | browserHistory.push('/home');
72 | }
73 | },
74 | error(error) {
75 | console.log(`Error subscribing to user: ${error.toString()}`);
76 | that.setState({
77 | loading: false,
78 | });
79 | }, // Network error, etc.
80 | complete() {
81 | // console.log(`Subscription complete`);
82 | },
83 | });
84 | this.setState({
85 | userSubscription: subscription,
86 | });
87 | }
88 |
89 | render() {
90 | return (
91 |
92 |
93 |
94 |
95 |
96 |
97 | );
98 | }
99 | }
100 |
101 | App.propTypes = {};
102 |
103 | export default App;
104 |
--------------------------------------------------------------------------------
/src/js/components/App/Description.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Row, Col } from 'react-bootstrap';
3 |
4 | const styles = {
5 | marketing: {
6 | margin: '40px 0',
7 | p: {
8 | marginTop: 28,
9 | },
10 | h4: {
11 | marginTop: 28,
12 | },
13 | },
14 | };
15 |
16 | class Description extends React.Component { // eslint-disable-line
17 | render() {
18 | return (
19 |
20 |
21 |
22 |
23 | This React.js boilerplate helps developers create modern, performant,
24 | and clean web apps with the help of Scaphold.io.
25 |
26 |
27 |
28 |
29 | Leverage the simplicity and power of Apollo Client and GraphQL to manage
30 | your application's data store.
31 |
32 |
33 |
34 |
35 |
36 |
37 | Smoothe and creative components to fit the way you want your apps to be experienced.
38 |
39 |
40 |
41 |
42 | Webpack is a module bundler that helps you serve your application in any environment
43 | with hot reloading.
44 |
45 |
46 |
47 | );
48 | }
49 | }
50 |
51 | export default Description;
52 |
--------------------------------------------------------------------------------
/src/js/components/App/Footer.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import FontAwesome from 'react-fontawesome';
3 |
4 | const styles = {
5 | footer: {
6 | textAlign: 'center',
7 | paddingTop: 20,
8 | color: '#777',
9 | borderTop: '1px, solid, #e5e5e5',
10 | },
11 | };
12 |
13 | class Footer extends React.Component { // eslint-disable-line
14 | render() {
15 | return (
16 | Made with from the Scaphold Team
17 | );
18 | }
19 | }
20 |
21 | export default Footer;
22 |
--------------------------------------------------------------------------------
/src/js/components/App/Header.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Link, browserHistory } from 'react-router';
3 | import { Navbar, Nav, NavItem } from 'react-bootstrap';
4 | import Login from './Login';
5 | import Register from './Register';
6 |
7 | class Header extends React.Component {
8 | constructor(props) {
9 | super(props);
10 | this.state = {
11 | showModal: false,
12 | };
13 | }
14 |
15 | goToGraphiQL() {
16 | browserHistory.push('/graphiql');
17 | }
18 |
19 | goHome() {
20 | browserHistory.push('/');
21 | }
22 |
23 | render() {
24 | return (
25 |
26 |
27 |
28 | Scaphold
29 |
30 |
31 |
32 | Home
33 | GraphiQL
34 |
35 |
36 |
37 |
38 | );
39 | }
40 | }
41 |
42 | export default Header;
43 |
44 | const styles = {
45 | navbar: {
46 | marginBottom: 0,
47 | },
48 | };
49 |
--------------------------------------------------------------------------------
/src/js/components/App/Hero.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Row, Col, Button, Jumbotron} from 'react-bootstrap';
3 | import FontAwesome from 'react-fontawesome';
4 |
5 | class Hero extends React.Component {
6 | render() {
7 | return (
8 |
9 |
10 |
11 | Welcome!
12 |
13 |
14 | Here you'll find Scaphold.io 's Boilerplate React-Apollo template
15 |
16 |
17 |
18 |
19 | Learn more
20 | Join our Slack
21 |
22 |
23 |
24 |
25 | );
26 | }
27 | }
28 |
29 | export default Hero;
30 |
31 | const styles = {
32 | jumbotron: {
33 | marginTop: 20,
34 | borderRadius: 10,
35 | textAlign: 'center'
36 | },
37 | scaphold: {
38 | color: '#1DAAA0'
39 | },
40 | slack: {
41 | color: 'white',
42 | backgroundColor: '#1DAAA0'
43 | }
44 | };
45 |
--------------------------------------------------------------------------------
/src/js/components/App/Login.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { graphql } from 'react-apollo';
3 | import gql from 'graphql-tag';
4 | import { browserHistory } from 'react-router';
5 | import { Button, Modal, OverlayTrigger, NavItem, Form, FormControl, FormGroup, Row, Col, ControlLabel, Alert } from 'react-bootstrap';
6 | import config from './../../../config';
7 |
8 | const LoginUserMutation = gql `
9 | mutation LoginUserMutation($data: LoginUserInput!) {
10 | loginUser(input: $data) {
11 | token
12 | user {
13 | id
14 | username
15 | }
16 | }
17 | }
18 | `;
19 |
20 | class Login extends React.Component {
21 |
22 | constructor(props) {
23 | super(props);
24 | this.state = {
25 | showModal: false,
26 | loginEmail: '',
27 | loginPassword: '',
28 | errors: []
29 | };
30 | this.close = this.close.bind(this);
31 | this.open = this.open.bind(this);
32 | this._handleLoginEmailChange = this._handleLoginEmailChange.bind(this);
33 | this._handleLoginPasswordChange = this._handleLoginPasswordChange.bind(this);
34 | this.validateInput = this.validateInput.bind(this);
35 | this.loginUser = this.loginUser.bind(this);
36 | }
37 |
38 | close() {
39 | this.setState({ showModal: false });
40 | }
41 |
42 | open() {
43 | this.setState({ showModal: true });
44 | }
45 |
46 | _handleLoginEmailChange(e) {
47 | this.setState({
48 | loginEmail: e.target.value
49 | });
50 | }
51 |
52 | _handleLoginPasswordChange(e) {
53 | this.setState({
54 | loginPassword: e.target.value
55 | });
56 | }
57 |
58 | validateInput() {
59 | return (
60 | this.state.loginEmail && this.state.loginEmail.length &&
61 | this.state.loginPassword && this.state.loginPassword.length
62 | );
63 | }
64 |
65 | loginUser() {
66 | if (this.validateInput()) {
67 | this.props.login({
68 | username: this.state.loginEmail,
69 | password: this.state.loginPassword
70 | }).then(({ data }) => {
71 | if (!data.errors) {
72 | localStorage.setItem('token', data.loginUser.token);
73 | localStorage.setItem('user', JSON.stringify(data.loginUser.user));
74 | this.setState({ errors: [] });
75 | browserHistory.push('/home');
76 | } else {
77 | this.setState({ errors: data.errors });
78 | }
79 | }).catch(errors => {
80 | this.setState({ errors: errors.graphQLErrors });
81 | });
82 | } else {
83 | this.setState({
84 | errors: [{
85 | message: 'Username or password was not filled out. Please fill out the required fields.'
86 | }]
87 | });
88 | }
89 | }
90 |
91 | render() {
92 | return (
93 |
94 | Login
95 |
96 |
97 |
98 | Login Here!
99 |
100 |
101 |
102 | {this.state.errors.map((err, i) =>
{err.message} )}
103 |
104 |
123 |
124 |
125 | Login
126 | Close
127 |
128 |
129 |
130 | );
131 | }
132 | }
133 |
134 | const styles = {
135 | errors: {
136 | textAlign: 'left',
137 | color: 'red'
138 | }
139 | };
140 |
141 | const LoginWithData = graphql(LoginUserMutation, {
142 | props: ({ mutate }) => ({
143 | login: (data) => mutate({
144 | variables: {
145 | data,
146 | },
147 | }),
148 | }),
149 | })(Login);
150 | export default LoginWithData;
151 |
--------------------------------------------------------------------------------
/src/js/components/App/Register.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { graphql } from 'react-apollo';
3 | import gql from 'graphql-tag';
4 | import { browserHistory } from 'react-router';
5 | import { Button, Modal, NavItem, Form, FormControl, FormGroup, Row, Col, ControlLabel, Alert } from 'react-bootstrap';
6 |
7 | const CreateUserMutation = gql `
8 | mutation CreateUserMutation($data: CreateUserInput!) {
9 | createUser(input: $data) {
10 | token
11 | changedUser {
12 | id
13 | username
14 | }
15 | }
16 | }
17 | `;
18 |
19 | class Register extends React.Component {
20 |
21 | constructor(props) {
22 | super(props);
23 |
24 | this.state = {
25 | showModal: false,
26 | registerEmail: '',
27 | registerPassword: '',
28 | errors: []
29 | };
30 |
31 | this.close = this.close.bind(this);
32 | this.open = this.open.bind(this);
33 | this._handleRegisterEmailChange = this._handleRegisterEmailChange.bind(this);
34 | this._handleRegisterPasswordChange = this._handleRegisterPasswordChange.bind(this);
35 | this.validateInput = this.validateInput.bind(this);
36 | this.registerUser = this.registerUser.bind(this);
37 | }
38 |
39 | close() {
40 | this.setState({ showModal: false });
41 | }
42 |
43 | open() {
44 | this.setState({ showModal: true });
45 | }
46 |
47 | validateInput() {
48 | return (
49 | this.state.registerEmail && this.state.registerEmail.length &&
50 | this.state.registerPassword && this.state.registerPassword.length
51 | );
52 | }
53 |
54 | registerUser() {
55 | if (this.validateInput()) {
56 | this.props.register({
57 | username: this.state.registerEmail,
58 | password: this.state.registerPassword,
59 | }).then(({ data }) => {
60 | if (!data.errors) {
61 | localStorage.setItem('token', data.createUser.token);
62 | localStorage.setItem('user', JSON.stringify(data.createUser.changedUser));
63 | this.setState({ errors: [] });
64 | browserHistory.push('/home');
65 | } else {
66 | this.setState({ errors: data.errors });
67 | }
68 | }).catch((errors) => {
69 | this.setState({ errors: errors.graphQLErrors });
70 | });
71 | } else {
72 | this.setState({
73 | errors: [{
74 | message: 'Username or password was not filled out. Please fill out the required fields.'
75 | }]
76 | });
77 | }
78 | }
79 |
80 | _handleRegisterEmailChange(e) {
81 | this.setState({
82 | registerEmail: e.target.value
83 | });
84 | }
85 |
86 | _handleRegisterPasswordChange(e) {
87 | this.setState({
88 | registerPassword: e.target.value
89 | });
90 | }
91 |
92 | render() {
93 | return (
94 |
95 | Register
96 |
97 |
98 |
99 | Register Here!
100 |
101 |
102 |
103 | {this.state.errors.map((err, i) =>
{err.message} )}
104 |
105 |
126 |
127 |
128 | Register
129 | Close
130 |
131 |
132 |
133 | );
134 | }
135 | }
136 |
137 | const styles = {
138 | errors: {
139 | textAlign: 'left',
140 | color: 'red'
141 | }
142 | };
143 |
144 | const RegisterWithData = graphql(CreateUserMutation, {
145 | props: ({ mutate }) => ({
146 | register: (data) => mutate({
147 | variables: {
148 | data,
149 | },
150 | }),
151 | }),
152 | })(Register);
153 | export default RegisterWithData;
154 |
--------------------------------------------------------------------------------
/src/js/components/GraphiQL/GraphiQL.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import GraphiQL from 'graphiql';
3 | import fetch from 'isomorphic-fetch';
4 | import config from './../../../config';
5 | import Header from './../App/Header';
6 | import LoggedInHeader from './../Home/Header';
7 |
8 | function graphQLFetcher(graphQLParams) {
9 | return fetch(config.scapholdUrl, {
10 | method: 'post',
11 | headers: {
12 | 'Content-Type': 'application/json',
13 | Authorization: localStorage.token ? `Bearer ${localStorage.token}` : '',
14 | },
15 | body: JSON.stringify(graphQLParams),
16 | }).then(response => response.json());
17 | }
18 |
19 | class GraphiQLModule extends React.Component {
20 | render() {
21 | let header;
22 | if (!localStorage.token) {
23 | header = ;
24 | }
25 | else {
26 | header = ;
27 | }
28 |
29 | return (
30 |
31 | {header}
32 |
33 |
34 | )
35 | }
36 | }
37 |
38 | export default GraphiQLModule;
39 |
--------------------------------------------------------------------------------
/src/js/components/Home/Body.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Row, Col, Button} from 'react-bootstrap';
3 | import Description from '../App/Description';
4 | import FontAwesome from 'react-fontawesome';
5 |
6 | class Body extends React.Component {
7 | render() {
8 | const user = JSON.parse(localStorage.getItem('user'));
9 | const loggedInUser = user ? user.username : '';
10 |
11 | return (
12 |
13 |
14 | Welcome, you've successfully logged in to Scaphold 's React Apollo Starter Kit!
15 |
16 |
17 |
18 | {
19 | loggedInUser ? (
20 |
21 | Username: {loggedInUser}
22 |
23 | ) : ''
24 | }
25 |
26 | Feel free to poke around and check out the other functionality that this starter kit provides.
27 | We've put together a couple tools for you to get this starter kit rolling.
28 |
29 |
30 | So by all means, modify the code, break it, and learn about the same awesome technology that Facebook is built on.
31 |
32 |
33 | Learn more
34 | Join our Slack
35 |
36 |
37 |
38 |
39 |
40 | );
41 | }
42 | }
43 |
44 | const styles = {
45 | heading: {
46 | padding: '100px 0 50px 0',
47 | fontSize: '25px',
48 | textAlign: 'center'
49 | },
50 | subheading: {
51 | padding: '0 0 50px 0',
52 | fontSize: '18px',
53 | textAlign: 'center',
54 | section: {
55 | padding: '25px'
56 | }
57 | },
58 | scaphold: {
59 | color: '#1DAAA0'
60 | },
61 | slack: {
62 | color: 'white',
63 | backgroundColor: '#1DAAA0'
64 | }
65 | };
66 |
67 | export default Body;
68 |
--------------------------------------------------------------------------------
/src/js/components/Home/Header.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { graphql } from 'react-apollo';
3 | import gql from 'graphql-tag';
4 | import { Link, browserHistory } from 'react-router';
5 | import { Navbar, Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
6 | import Logout from './Logout';
7 |
8 | class Header extends React.Component {
9 | constructor(props) {
10 | super(props);
11 |
12 | this.goToGraphiQL = this.goToGraphiQL.bind(this);
13 | this.goHome = this.goHome.bind(this);
14 | }
15 |
16 | goToGraphiQL() {
17 | browserHistory.push('/graphiql');
18 | }
19 |
20 | goHome() {
21 | browserHistory.push('/home');
22 | }
23 |
24 | render() {
25 | const user = JSON.parse(localStorage.getItem('user'));
26 | const loggedInUser = user ? user.username : '';
27 |
28 | return (
29 |
30 |
31 |
32 | Scaphold
33 |
34 |
35 |
36 | Home
37 | GraphiQL
38 | {loggedInUser}
39 |
40 |
41 |
42 | );
43 | }
44 | }
45 |
46 | const styles = {
47 | navbar: {
48 | marginBottom: 0
49 | }
50 | };
51 |
52 | export default Header;
53 |
54 |
--------------------------------------------------------------------------------
/src/js/components/Home/Home.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Button} from 'react-bootstrap';
3 | import {browserHistory} from 'react-router';
4 | import Header from './Header';
5 | import Body from './Body';
6 |
7 | class Home extends React.Component {
8 | render() {
9 | if (!localStorage.token) {
10 | browserHistory.push('/');
11 | }
12 |
13 | return (
14 |
15 |
16 |
17 |
18 | );
19 | }
20 | }
21 |
22 | export default Home;
23 |
--------------------------------------------------------------------------------
/src/js/components/Home/Logout.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { browserHistory } from 'react-router';
3 | import { NavItem } from 'react-bootstrap';
4 |
5 | class Logout extends React.Component {
6 |
7 | constructor(props) {
8 | super(props);
9 | this.logoutUser = this.logoutUser.bind(this);
10 | }
11 |
12 | logoutUser() {
13 | localStorage.clear();
14 | browserHistory.push('/');
15 | }
16 |
17 | render() {
18 | return (
19 | Logout
20 | );
21 | }
22 | }
23 |
24 | export default Logout;
25 |
--------------------------------------------------------------------------------
/src/server.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 | const webpack = require('webpack'); // eslint-disable-line
4 | const WebpackDevServer = require('webpack-dev-server'); // eslint-disable-line
5 | const config = require('./config');
6 |
7 | const APP_PORT = 3001;
8 |
9 | // Production version
10 | let compiler = webpack({
11 | entry: path.join(process.cwd(), 'lib', 'js', 'app.js'),
12 | module: {
13 | loaders: [
14 | {
15 | exclude: /node_modules/,
16 | // loader: 'babel-loader',
17 | test: /\.js$/,
18 | },
19 | ],
20 | },
21 | output: {
22 | path: path.join(process.cwd(), 'lib'), // sets our output directory to lib/
23 | filename: 'app.js', // sets our output filename to server.js
24 | publicPath: '/js/',
25 | },
26 | });
27 |
28 | let app;
29 | if (process.env.NODE_ENV !== 'production') {
30 | compiler = webpack({
31 | entry: path.join(process.cwd(), 'src', 'js', 'app.js'),
32 | module: {
33 | loaders: [
34 | {
35 | exclude: /node_modules/,
36 | loader: 'babel-loader',
37 | test: /\.js$/,
38 | },
39 | ],
40 | },
41 | output: {
42 | path: path.join(process.cwd(), 'src'), // sets our output directory to lib/
43 | filename: 'app.js', // sets our output filename to server.js
44 | publicPath: '/',
45 | },
46 | });
47 |
48 | app = new WebpackDevServer(compiler, {
49 | hot: true,
50 | contentBase: 'src/',
51 | publicPath: '/',
52 | proxy: { '/graphql': config.scapholdUrl },
53 | stats: {
54 | colors: true,
55 | },
56 | });
57 | } else {
58 | app = new WebpackDevServer(compiler, {
59 | hot: false,
60 | contentBase: 'src/',
61 | publicPath: '/',
62 | proxy: { '/graphql': config.scapholdUrl },
63 | stats: {
64 | colors: false,
65 | },
66 | });
67 | }
68 |
69 | // Serve static resources
70 | app.use('*', (req, res) => {
71 | fs.readFile(path.join(compiler.outputPath, 'index.html'), (err, file) => {
72 | if (err) {
73 | res.sendStatus(404);
74 | } else {
75 | res.send(file.toString());
76 | }
77 | });
78 | });
79 |
80 | app.listen(APP_PORT, () => {
81 | console.log(`App is now running on http://localhost:${APP_PORT}`);
82 | });
83 |
--------------------------------------------------------------------------------
/webpack/webpack.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * COMMON WEBPACK CONFIGURATION
3 | */
4 |
5 | const path = require('path');
6 | const HtmlWebpackPlugin = require('html-webpack-plugin');
7 | const CopyWebpackPlugin = require('copy-webpack-plugin');
8 | // console.log('dir');
9 | // console.log(path.resolve(process.cwd(), 'app/assets/styles'));
10 |
11 | module.exports = () => ({
12 | entry: path.join(process.cwd(), 'lib', 'js', 'app.js'),
13 | plugins: [
14 | new HtmlWebpackPlugin({
15 | template: 'src/index.html',
16 | minify: {
17 | removeComments: true,
18 | collapseWhitespace: true,
19 | removeRedundantAttributes: true,
20 | useShortDoctype: true,
21 | removeEmptyAttributes: true,
22 | removeStyleLinkTypeAttributes: true,
23 | keepClosingSlash: true,
24 | minifyJS: true,
25 | minifyCSS: true,
26 | minifyURLs: true,
27 | },
28 | inject: true,
29 | }),
30 | new CopyWebpackPlugin([
31 | // { from: 'src/images', to: 'assets/images' },
32 | ], {
33 | ignore: [],
34 |
35 | // By default, we only copy modified files during
36 | // a watch or webpack-dev-server build. Setting this
37 | // to `true` copies all files.
38 | copyUnmodified: true,
39 | }),
40 | ],
41 | module: {
42 | loaders: [
43 | {
44 | exclude: /node_modules/,
45 | // loader: 'babel-loader',
46 | test: /\.js$/,
47 | },
48 | ],
49 | },
50 | output: {
51 | path: path.join(process.cwd(), 'build'), // sets our output directory to build/
52 | filename: 'app.js', // sets our output filename to server.js
53 | publicPath: '/',
54 | },
55 | });
56 |
--------------------------------------------------------------------------------