master fb06742c53a3 cached
40 files
41.4 KB
10.9k tokens
65 symbols
1 requests
Download .txt
Repository: btomashvili/react-redux-firebase-boilerplate
Branch: master
Commit: fb06742c53a3
Files: 40
Total size: 41.4 KB

Directory structure:
gitextract_tc2n1gmc/

├── .babelrc
├── .editorconfig
├── .eslintrc
├── .firebaserc
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── database.rules.json
├── firebase.json
├── jsconfig.json
├── package.json
├── src/
│   ├── app/
│   │   ├── actions/
│   │   │   ├── firebase_actions.js
│   │   │   ├── index.js
│   │   │   └── types.js
│   │   ├── bundle.scss
│   │   ├── components/
│   │   │   ├── app.jsx
│   │   │   ├── app.scss
│   │   │   ├── helpers/
│   │   │   │   └── loading.jsx
│   │   │   ├── index_home.jsx
│   │   │   └── user/
│   │   │       ├── change_password.jsx
│   │   │       ├── login.jsx
│   │   │       ├── logout.jsx
│   │   │       ├── profile.jsx
│   │   │       ├── register.jsx
│   │   │       └── reset_password.jsx
│   │   ├── config.js
│   │   ├── index.jsx
│   │   ├── reducers/
│   │   │   ├── firebase_user_reducer.js
│   │   │   └── index.js
│   │   ├── routes.jsx
│   │   └── utils/
│   │       ├── authenticated.js
│   │       └── firebase.js
│   └── index.html
├── test/
│   ├── components/
│   │   └── app_test.js
│   └── test_helper.js
├── webpack/
│   ├── webpack-dev.config.js
│   ├── webpack-prod.config.js
│   └── webpack.config.js
└── www.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .babelrc
================================================
{
  "presets": ["react", "es2015", "stage-1"]
}


================================================
FILE: .editorconfig
================================================
# http://editorconfig.org
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 80
trim_trailing_whitespace = true

[*.md]
max_line_length = 0
trim_trailing_whitespace = false

[COMMIT_EDITMSG]
max_line_length = 0

================================================
FILE: .eslintrc
================================================
{
  "extends": "airbnb",
  "parserOptions": {
    "ecmaFeatures": {
      "experimentalObjectRestSpread": true
    }
  },
  "rules": {
    "max-len": ["warn", 120],
    "indent": ["warn", 4],
    "react/jsx-indent": ["warn", 4]
  },
  "globals": {
    "localStorage": true 
  }
}

================================================
FILE: .firebaserc
================================================
{
  "projects": {
    "default": "react-redux-firebase-d6283"
  }
}


================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*

#
dist

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules
jspm_packages

# Optional npm cache directory
.npm

# Optional REPL history
.node_repl_history
.idea/
.vscode
firebase-debug.log


================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
  - "node"
  - "6"
  - "5"
  - "4"

================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2016 btomashvili

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# THIS PROJECT IS DEPRECATED IT'S NOT MAINTAINED ANYMORE!


# React, Redux Firebase Boilerplate


[![Build Status](https://travis-ci.org/awwong1/react-redux-firebase-boilerplate.svg?branch=master)](https://travis-ci.org/awwong1/react-redux-firebase-boilerplate)

> [Firebase](https://www.firebase.com) is a powerful platform for your mobile and web applications that lets you build apps fast without managing servers. Firebase gives you the tools and infrastructure to build better apps and grow successful businesses.

> [React](https://www.firebase.com) A javascript library for building user interfaces

> [Redux](http://redux.js.org/) Redux is a predictable state container for JavaScript apps.

### Boilerplate Introduction
Boilerplate is designed for quickly spin up your apps with Firebase, using bunch of awesome new front-end technologies includes webpack build system, hot reloading, routing & sass support.

## Features
* [react](https://github.com/facebook/react)
* [redux](https://github.com/rackt/redux)
* [firebase](https://www.npmjs.com/package/firebase)
* [react-router](https://github.com/rackt/react-router)
* [redux-promise](https://github.com/acdlite/redux-promise)
* [webpack](https://github.com/webpack/webpack)
* [babel](https://github.com/babel/babel)

Quick Start
-----------

```shell
$ git clone https://github.com/btomashvili/react-redux-firebase-boilerplate.git
$ cd react-redux-firebase-boilerplate
$ npm install
$ npm run dev
```

Firebase settings
--------
First you need to create your firebase application to fetch settings for boilerplate. For more information how to add your web app check this [resource](https://firebase.google.com/docs/web/setup). After it copy your settings from firebase and fill config.js

```javascript
module.exports = {

    FIREBASE_CONFIG: {

      apiKey: "",
      authDomain: "",
      databaseURL: "",
      storageBucket: "",

    }
}
```

Commands
--------

|Script|Description|
|---|---|
|`npm run dev`| Run development server with webpack-dev-server @ `localhost:3000`|
|`npm run build`| Test, and build the application to `./dist`|
|`npm start`| Start production ready app with pm2 from `./dist` @ `localhost:8080`|
|`npm run lint`| Run ESLint on `./src`|


What it looks like

### DEMO 
[https://react-redux-firebase-d6283.firebaseapp.com/](https://react-redux-firebase-d6283.firebaseapp.com/)

--------

![screen](https://www.dropbox.com/s/csufxlitjme8p3q/react_redux_firebase.gif?raw=1 "react_redux_firebase_boilerplate")


================================================
FILE: database.rules.json
================================================
{
  "rules": {
    ".read": false,
    ".write": false,
    "words": {
      ".read": true,
      ".write": true
    },
    "dev": {
      ".read": true,
      ".write": true
    },
    "staging": {
      ".read": true,
      ".write": true
    }
  }
}

================================================
FILE: firebase.json
================================================
{
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "dist",
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}


================================================
FILE: jsconfig.json
================================================
{
    "compilerOptions": {
        "target": "ES6",
         "allowSyntheticDefaultImports": true
    },
    "exclude": [
        "node_modules"
    ]
}

================================================
FILE: package.json
================================================
{
  "name": "react-redux-firebase-boilerplate",
  "version": "1.0.0",
  "description": "Simple boilerplate for Reactjs with Redux and Firebase",
  "main": "index.jsx",
  "repository": "git@github.com:btomashvili/react-redux-firebase-boilerplate.git",
  "scripts": {
    "dev": "./node_modules/.bin/webpack-dev-server --config ./webpack/webpack-dev.config.js --watch --colors",
    "build": "rm -rf dist && ./node_modules/.bin/webpack --config ./webpack/webpack-prod.config.js --colors",
    "start": "PORT=8080 pm2 start ./www.js",
    "test": "./node_modules/.bin/eslint src && ./node_modules/.bin/mocha --compilers js:babel-core/register --require ./test/test_helper.js --recursive ./test",
    "test:watch": "npm run test -- --watch",
    "lint": "./node_modules/.bin/eslint src"
  },
  "author": "Beka Tomashvili",
  "contributors": [
    {
      "name": "Alexander Wong",
      "email": "admin@alexander-wong.com",
      "url": "https://www.alexander-wong.com/"
    }
  ],
  "license": "MIT",
  "keywords": [
    "ReactJS",
    "Redux",
    "Firebase",
    "React hot loader",
    "React Router",
    "ESLint"
  ],
  "devDependencies": {
    "babel-core": "^6.2.1",
    "babel-loader": "^6.2.0",
    "babel-preset-es2015": "^6.1.18",
    "babel-preset-react": "^6.1.18",
    "babel-preset-stage-1": "^6.5.0",
    "chai": "^3.5.0",
    "chai-jquery": "^2.0.0",
    "css-loader": "^0.23.1",
    "eslint": "^3.6.1",
    "eslint-config-airbnb": "^12.0.0",
    "eslint-plugin-import": "^1.16.0",
    "eslint-plugin-jsx-a11y": "^2.2.2",
    "eslint-plugin-react": "^6.3.0",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.9.0",
    "html-webpack-plugin": "^2.21.0",
    "imports-loader": "^0.6.5",
    "jquery": "^3.1.0",
    "jsdom": "^8.1.0",
    "mocha": "^2.4.5",
    "node-sass": "^3.8.0",
    "react-addons-test-utils": "^0.14.8",
    "react-hot-loader": "^1.3.0",
    "sass-loader": "^4.0.0",
    "style-loader": "^0.13.1",
    "url-loader": "^0.5.7",
    "webpack": "^1.12.9",
    "webpack-dev-server": "^1.14.0"
  },
  "dependencies": {
    "bootstrap-social": "^5.0.0",
    "eslint-config-airbnb": "^12.0.0",
    "eslint-plugin-import": "^2.0.0",
    "express": "^4.14.0",
    "firebase": "^3.0.5",
    "font-awesome": "^4.6.3",
    "lodash": "^3.10.1",
    "react": "^0.14.8",
    "react-dom": "^0.14.3",
    "react-redux": "^4.0.0",
    "react-router": "^2.0.0-rc5",
    "redux": "^3.0.4",
    "redux-logger": "^3.0.6",
    "redux-promise": "^0.5.3",
    "redux-thunk": "^2.1.0",
    "reduxsauce": "^0.5.0",
    "seamless-immutable": "^7.1.2"
  }
}


================================================
FILE: src/app/actions/firebase_actions.js
================================================
import {
  LOGIN_WITH_PROVIDER_FIREBASE,
  REGISTER_FIREBASE_USER,
  LOGIN_FIREBASE_USER,
  FETCH_FIREBASE_USER,
  UPDATE_FIREBASE_USER,
  CHANGE_FIREBASE_USER_PASSWORD,
  FIREBASE_PASSWORD_RESET_EMAIL,
  LOGOUT_FIREBASE_USER,
} from './types';


export function loginWithProvider(provider) {    
  return {
    type: LOGIN_WITH_PROVIDER_FIREBASE,
    provider,
  };
}

export function registerUser(user) {    
  return {
    type: REGISTER_FIREBASE_USER,
    user
  };
}

export function loginUser(user) {    
  return {
      type: LOGIN_FIREBASE_USER,
      user
  };
}

export function fetchUser() {  
  return {
    type: FETCH_FIREBASE_USER    
  };
}

export function updateUser(user) {
  return {
    type: UPDATE_FIREBASE_USER,
    user
  };
}

export function changePassword(newPassword) {  
  return {
    type: CHANGE_FIREBASE_USER_PASSWORD,
    newPassword
  };
}

export function resetPasswordEmail(email) {  
  return {
    type: FIREBASE_PASSWORD_RESET_EMAIL,
    email
  };
}

export function logoutUser(user) {  
  return {
    type: LOGOUT_FIREBASE_USER,
    user
  };
}


================================================
FILE: src/app/actions/index.js
================================================


================================================
FILE: src/app/actions/types.js
================================================


// / FIREBASE AUTH ACTIONS
export const LOGIN_WITH_PROVIDER_FIREBASE = 'LOGIN_WITH_PROVIDER_FIREBASE';
export const REGISTER_FIREBASE_USER = 'REGISTER_FIREBASE_USER';
export const LOGIN_FIREBASE_USER = 'LOGIN_FIREBASE_USER';
export const FETCH_FIREBASE_USER = 'FETCH_FIREBASE_USER';
export const UPDATE_FIREBASE_USER = 'UPDATE_FIREBASE_USER';
export const CHANGE_FIREBASE_USER_PASSWORD = 'CHANGE_FIREBASE_USER_PASSWORD';
export const FIREBASE_PASSWORD_RESET_EMAIL = 'FIREBASE_PASSWORD_RESET_EMAIL';
export const LOGOUT_FIREBASE_USER = 'LOGOUT_FIREBASE_USER';


================================================
FILE: src/app/bundle.scss
================================================
@import './components/app';

================================================
FILE: src/app/components/app.jsx
================================================
import React, { Component } from 'react';
import { Link } from 'react-router';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { fetchUser, logoutUser } from '../actions/firebase_actions';
import FireBaseTools from '../utils/firebase'

console.log(FireBaseTools.getDatabaseReference);

class App extends Component {

  constructor(props) {
    super(props);

    this.props.fetchUser();    
  }

  _logOut() {
    this.props.logoutUser().then((data) => {
      // reload props from reducer
      this.props.fetchUser();
    });
  }

  _read() {
    FireBaseTools.getDatabaseReference('/DongerMaster').once('value').then(function(snapshot) {
      console.log(snapshot.val());
    });
  }

  _write() {
    FireBaseTools.getDatabaseReference('/').set({DongerMaster: 'lul'});
  }

  _renderUserMenu(currentUser) {
    // if current user exists and user id exists than make user navigation
    if (currentUser && currentUser.uid) {
      return (
        <li className="dropdown">
          <a
            href="#" className="dropdown-toggle" data-toggle="dropdown" role="button"
            aria-haspopup="true" aria-expanded="false"
          > {currentUser.email}<span className="caret" />
          </a>
          <ul className="dropdown-menu">
            <li><Link to="/profile">Profile</Link></li>
            <li role="separator" className="divider" />
            <li><Link to="/logout" onClick={() => this._logOut}>Logout</Link></li>
          </ul>
        </li>
      );
    } else {
      return [
        <li key={1}><Link to="/login">Login</Link></li>,
        <li key={2}><Link to="/register">Register</Link></li>,
      ];
    }
  }

  render() {
    return (      
      <div>
      <button onClick={() => this._read()}>read</button>
      <button onClick={() => this._write()}>write</button>
        <header className="navbar navbar-static-top navbar-inverse" id="top" role="banner">
          <div className="container">
            <div className="navbar-header">
              <button
                className="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target=".bs-navbar-collapse">
                <span className="sr-only">Toggle navigation</span>
                <span className="icon-bar" />
                <span className="icon-bar" />
                <span className="icon-bar" />
              </button>
              <Link to="/" className="navbar-brand">Firebase & Redux boilerplate</Link>
              </div>
              <nav className="collapse navbar-collapse bs-navbar-collapse" role="navigation">
                <ul className="nav navbar-nav">
                  <li><Link to="/"> Home</Link></li>,
                </ul>
                <ul className="nav navbar-nav navbar-right">
                    { this._renderUserMenu(this.props.currentUser) }
                </ul>
              </nav>
          </div>
        </header>

        <div className="container">
         {this.props.children}
        </div>
      </div>
    );
  }
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ fetchUser, logoutUser }, dispatch);
}


function mapStateToProps(state) {
  return { currentUser: state.currentUser };
}


export default connect(mapStateToProps, mapDispatchToProps)(App);


================================================
FILE: src/app/components/app.scss
================================================
body {
  font-size: 16px;
}


================================================
FILE: src/app/components/helpers/loading.jsx
================================================
import React from 'react';


const Loading = () => {
    return (
    <div className="col-md-4">
      Loading ....
    </div>
  );
};

export default Loading;


================================================
FILE: src/app/components/index_home.jsx
================================================
import React from 'react';

export default () => {
  return <div> Home Page of our application! </div>;
};


================================================
FILE: src/app/components/user/change_password.jsx
================================================
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { changePassword } from '../../actions/firebase_actions';

class ChangePassword extends Component {

  constructor(props) {
      super(props);
      this.onFormSubmit = this.onFormSubmit.bind(this);
      this.state = {
        message: '',
    };
  }

  onFormSubmit(event) {
      event.preventDefault();
      let password = this.refs.password.value;
      let repeatPassword = this.refs.repeatPassword.value;
      if (password !== repeatPassword) {
        this.setState({
          message: 'Please password must match!',
      });
    } else {
        this.props.changePassword(password).then((data) => {
          if (data.payload.errorCode)
            this.setState({ message: data.payload.errorMessage });
          else
          this.setState({ message: 'Password was changed!' });
      });
    }
  }

    render() {
      return (
      <form id="ChangePassword" role="form" onSubmit={this.onFormSubmit}>
        <h4> Change Password </h4>
        <h5> {this.state.message} </h5>
        <div className="form-group">
          <label htmlFor="password"> New Password: </label>
          <input type="password" className="form-control"
            name="password" ref="password" id="password" 
          />
        </div>
        <div className="form-group">
          <label htmlFor="repeatPassword"> Repeat Password: </label>
          <input type="password" className="form-control"
            name="repeatPassword" ref="repeatPassword" id="repeatPassword" 
          />

        </div>
        <button type="submit" className="btn btn-primary">Change Password</button>
      </form>
    );
  }

}


function mapDispatchToProps(dispatch) {
    return bindActionCreators({ changePassword }, dispatch);
}

function mapStateToProps(state) {
    return { currentUser: state.currentUser };
}

export default connect(mapStateToProps, mapDispatchToProps)(ChangePassword);


================================================
FILE: src/app/components/user/login.jsx
================================================
import React, { Component } from 'react';
import { browserHistory, Link } from 'react-router';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { loginUser, fetchUser, loginWithProvider } from '../../actions/firebase_actions';


class UserLogin extends Component {

    constructor(props) {
        super(props);
        this.onFormSubmit = this.onFormSubmit.bind(this);
        this.loginWithProvider = this.loginWithProvider.bind(this);
        this.state = {
            message: '',
        };
    }

    onFormSubmit(event) {
        event.preventDefault();

        const email = this.refs.email.value;
        const password = this.refs.password.value;
        this.props.loginUser({ email, password }).then((data) => {
            if (data.payload.errorCode) {
                this.setState({ message: data.payload.errorMessage });
            } else {
                browserHistory.push('/profile');
            }
        }
    );
    }

    loginWithProvider(provider) {
        this.props.loginWithProvider(provider).then((data) => {
            if (data.payload.errorCode) {
                this.setState({ message: data.payload.errorMessage });
            } else {
                browserHistory.push('/profile');
            }
        });
    }

    render() {
        return (
            <div className="col-md-4">
                <form id="frmLogin" role="form" onSubmit={this.onFormSubmit}>
                    <p>
                        {this.state.message}
                    </p>
                    <h2>Login</h2>
                    <div className="form-group">
                        <label htmlFor="txtEmail">Email address</label>
                        <input
                          type="email" className="form-control" id="txtEmail" ref="email" placeholder="Enter email"
                          name="email"
                        />
                    </div>
                    <div className="form-group">
                        <label htmlFor="txtPass">Password</label>
                        <input
                          type="password" className="form-control" id="txtPass" ref="password" placeholder="Password"
                          name="password"
                        />
                    </div>
                    <button type="submit" className="btn btn-default btn-block">Login</button>
                    <br />
                    <h5><Link to="/reset">Forgot password?</Link></h5>

                    <h4>Login with</h4>
                    <a
                      href="#" className="btn btn-block btn-social btn-facebook" onClick={() => {
                          this.loginWithProvider('facebook');
                      }} data-provider="facebook"
                    >Facebook</a>

                    <a
                      href="#" className="btn btn-block btn-social btn-twitter" onClick={() => {
                          this.loginWithProvider('twitter');
                      }} data-provider="twitter"
                    >Twitter</a>

                    <a
                      href="#" className="btn btn-block btn-social btn-google" onClick={() => {
                          this.loginWithProvider('google');
                      }} data-provider="twitter"
                    >Google</a>

                    <a
                      href="#" className="btn btn-block btn-social btn-github" onClick={() => {
                          this.loginWithProvider('github');
                      }} data-provider="twitter"
                    >Github</a>

                </form>
            </div>

        );
    }

}

function mapDispatchToProps(dispatch) {
    return bindActionCreators({
        loginUser,
        fetchUser,
        loginWithProvider,
    }, dispatch);
}

function mapStateToProps(state) {
    return { currentUser: state.currentUser };
}

export default connect(mapStateToProps, mapDispatchToProps)(UserLogin);


================================================
FILE: src/app/components/user/logout.jsx
================================================
import React from 'react';


export default () => (
    <form id="frmLogout" role="form">
        <h2>You are logged out!</h2>
    </form>
  );


================================================
FILE: src/app/components/user/profile.jsx
================================================
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import firebase from '../../utils/firebase';


import { fetchUser, updateUser } from '../../actions/firebase_actions';
import Loading from '../helpers/loading';
import ChangePassword from './change_password';

class UserProfile extends Component {

    constructor(props) {
        super(props);
        this.props.fetchUser();
        this.state = {
            message: '',
        };
        this.onFormSubmit = this.onFormSubmit.bind(this);
    }

    onFormSubmit(event) {
        event.preventDefault();
        const email = this.refs.email.value;
        const displayName = this.refs.displayName.value;
        this.props.updateUser({ email, displayName }).then((data) => {
            if (data.payload.errorCode) {
                this.setState({ message: data.payload.errorMessage });
            } else {
                this.setState({
                    message: 'Updated successfuly!',
                });
            }
        }
    );
    }

    render() {
        if (!this.props.currentUser) {
            return <Loading />;
        }

        return (
            <div className="col-md-6">
                <form id="frmProfile" role="form" onSubmit={this.onFormSubmit}>
                    <h2>User Profile Page</h2>
                    <p>{this.state.message}</p>
                    <br />
                    <div className="form-group">
                        <label htmlFor="email">Email: </label>
                        <input
                          type="text" defaultValue={this.props.currentUser.email}
                          className="form-control" id="email" ref="email" placeholder="Email" name="email"
                        />
                    </div>
                    <div className="form-group">
                        <label htmlFor="displayName">Display name: </label>
                        <input
                          type="text" defaultValue={this.props.currentUser.displayName}
                          className="form-control" ref="displayName" id="displayName" placeholder="Display name"
                          name="displayName"
                        />
                    </div>
                    <button type="submit" className="btn btn-primary">Update</button>
                </form>
                <ChangePassword />
            </div>
        );
    }

}


function mapDispatchToProps(dispatch) {
    return bindActionCreators({ fetchUser, updateUser }, dispatch);
}


function mapStateToProps(state) {
    return { currentUser: state.currentUser };
}


export default connect(mapStateToProps, mapDispatchToProps)(UserProfile);


================================================
FILE: src/app/components/user/register.jsx
================================================
import React, { Component } from 'react';
import { browserHistory } from 'react-router';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { registerUser } from '../../actions/firebase_actions';

class UserRegister extends Component {
    constructor(props) {
        super(props);
        this.onFormSubmit = this.onFormSubmit.bind(this);
        this.state = {
            message: '',
        };
    }

    onFormSubmit(event) {
        event.preventDefault();

        const email = this.refs.email.value;
        const password = this.refs.password.value;
        this.props.registerUser({ email, password }).then((data) => {
            if (data.payload.errorCode) {
                this.setState({ message: data.payload.errorMessage })
              ;
            } else {
                browserHistory.push('/profile');
            }
        }
    );
    }

    render() {
        return (
            <div className="col-md-4">
                <form id="frmRegister" role="form" onSubmit={this.onFormSubmit}>
                    <p>{this.state.message}</p>
                    <h2>Register</h2>
                    <div className="form-group">
                        <label htmlFor="txtRegEmail">Email address</label>
                        <input
                          type="email" className="form-control" ref="email" id="txtEmail" placeholder="Enter email"
                          name="email"
                        />
                    </div>
                    <div className="form-group">
                        <label htmlFor="txtRegPass">Password</label>
                        <input
                          type="password" className="form-control" ref="password" id="txtPass" placeholder="Password"
                          name="password"
                        />
                    </div>
                    <button type="submit" className="btn btn-default">Register</button>
                    <br /> <br />

                    <a
                      href="#" className="btn btn-block btn-social btn-facebook" onClick={() => {
                          this.loginWithProvider('facebook');
                      }} data-provider="facebook"
                    >Facebook</a>
                    <a
                      href="#" className="btn btn-block btn-social btn-twitter" onClick={() => {
                          this.loginWithProvider('twitter');
                      }} data-provider="twitter"
                    >Twitter</a>
                    <a
                      href="#" className="btn btn-block btn-social btn-google" onClick={() => {
                          this.loginWithProvider('google');
                      }} data-provider="twitter"
                    >Google</a>
                    <a
                      href="#" className="btn btn-block btn-social btn-github" onClick={() => {
                          this.loginWithProvider('github');
                      }} data-provider="twitter"
                    >Github</a>

                </form>
            </div>
        );
    }

}

function mapDispatchToProps(dispatch) {
    return bindActionCreators({
        registerUser,
    }, dispatch);
}

function mapStateToProps(state) {
    return { currentUser: state.currentUser };
}

export default connect(mapStateToProps, mapDispatchToProps)(UserRegister);


================================================
FILE: src/app/components/user/reset_password.jsx
================================================
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { resetPasswordEmail } from '../../actions/firebase_actions';

class ResetPassword extends Component {
    constructor(props) {
        super(props);
        this.state = {
            message: '',
        };
        this.onFormSubmit = this.onFormSubmit.bind(this);
    }

    onFormSubmit(event) {
        event.preventDefault();
        const email = this.refs.email.value;
        this.props.resetPasswordEmail(email).then((data) => {
            if (data.payload.errorCode) {
                this.setState({ message: data.payload.errorMessage });
            } else {
                this.setState({ message: 'Please see your email!' });
            }
        });
    }

    render() {
        return (

            <div className="col-md-4">
                <form role="form" onSubmit={this.onFormSubmit}>
                  <h4>{this.state.message}</h4>
                  <div className="form-group">
                    <label htmlFor="txtEmail">Email address</label>
                    <input
                    type="email" className="form-control" id="txtEmail" ref="email" placeholder="Enter email"
                    name="email"
                  />
                </div>
                  <button type="submit" className="btn btn-default btn-block">Reset Password</button>
              </form>
            </div>

        );
    }
}

function mapDispatchToProps(dispatch) {
    return bindActionCreators({
        resetPasswordEmail,
    }, dispatch);
}

export default connect(null, mapDispatchToProps)(ResetPassword);


================================================
FILE: src/app/config.js
================================================
module.exports = {

  // Change this to your firebase configuration! (Add Firebase to your web app)
    FIREBASE_CONFIG: {
      apiKey: "AIzaSyBgD4q3YujiPOOt4sPAfBHzBtG6xENp-TE",
      authDomain: "adwebsite-928a9.firebaseapp.com",
      databaseURL: "https://adwebsite-928a9.firebaseio.com",
      projectId: "adwebsite-928a9",
      storageBucket: "adwebsite-928a9.appspot.com",
      messagingSenderId: "72060758788"
    },
};


================================================
FILE: src/app/index.jsx
================================================
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from 'redux';
import { Router, browserHistory } from 'react-router';
import { createLogger } from 'redux-logger';
import ReduxPromise from 'redux-promise';


import reducers from './reducers';
import routes from './routes';

import 'bootstrap-social';

// for bundling your styles
import './bundle.scss';

const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);

// Redux Dev tools
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const logger = createLogger();

const enhancers = [applyMiddleware(ReduxPromise, logger)];

const store = createStore(reducers, composeEnhancers(...enhancers));

ReactDOM.render(
    <Provider store={store}>
        <Router history={browserHistory} routes={routes} />
    </Provider>, 
    document.querySelector('.react-root')
);


================================================
FILE: src/app/reducers/firebase_user_reducer.js
================================================
import FireBaseTools from '../utils/firebase';
import {
  LOGIN_WITH_PROVIDER_FIREBASE,
  REGISTER_FIREBASE_USER,
  LOGIN_FIREBASE_USER,
  FETCH_FIREBASE_USER,
  UPDATE_FIREBASE_USER,
  CHANGE_FIREBASE_USER_PASSWORD,
  FIREBASE_PASSWORD_RESET_EMAIL,
  LOGOUT_FIREBASE_USER,
} from '../actions/types';


export default function (state = null, action) {
  switch (action.type) {
    
  case FETCH_FIREBASE_USER:
    return fetchUser();

  case LOGOUT_FIREBASE_USER:
    return logoutUser(action.user);

  case REGISTER_FIREBASE_USER:
    return registerUser(action.user);

  case LOGIN_FIREBASE_USER:
    return loginUser(action.user);

  case UPDATE_FIREBASE_USER:
    return updateUser(action.user);

  case CHANGE_FIREBASE_USER_PASSWORD:
    return changePassword(action.newPassword);

  case FIREBASE_PASSWORD_RESET_EMAIL:
    return resetPasswordEmail(action.email);

  case LOGIN_WITH_PROVIDER_FIREBASE:
    return loginWithProvider(action.provider);

  default:
    return state;

  }
}

function loginWithProvider(provider) {
  FireBaseTools.loginWithProvider(provider);
}

function registerUser(user) {
  FireBaseTools.registerUser(user);
}

function loginUser(user) {
  FireBaseTools.loginUser(user);
}

function fetchUser() {
  FireBaseTools.fetchUser();
}

function updateUser(user) {
  FireBaseTools.updateUserProfile(user);
}

function changePassword(newPassword) {
  FireBaseTools.changePassword(newPassword);
}

function resetPasswordEmail(email) {
  FireBaseTools.resetPasswordEmail(email);
}

function logoutUser(user) {
  FireBaseTools.logoutUser(user);
}


================================================
FILE: src/app/reducers/index.js
================================================
import { combineReducers } from 'redux';
import FireBaseUserReducer from './firebase_user_reducer';

const rootReducer = combineReducers({
    currentUser: FireBaseUserReducer,
});

export default rootReducer;


================================================
FILE: src/app/routes.jsx
================================================
import React from 'react';
import { Route, IndexRoute } from 'react-router';
import App from './components/app';

import HomeIndex from './components/index_home';
import UserLogin from './components/user/login';
import UserLogout from './components/user/logout';
import UserRegister from './components/user/register';
import UserProfile from './components/user/profile';
import ResetPassword from './components/user/reset_password';
import requireAuth from './utils/authenticated';

export default (
    <Route path="/" component={App}>
        <IndexRoute component={HomeIndex} />
        <Route path="/login" component={UserLogin} />
        <Route path="/logout" component={UserLogout} />
        <Route path="/register" component={UserRegister} />
        <Route path="/reset" component={ResetPassword} />
        <Route path="/profile" component={UserProfile} onEnter={requireAuth} />
    </Route>

);


================================================
FILE: src/app/utils/authenticated.js
================================================
function requireAuth(nextState, replace) {
    const key = Object.keys(localStorage).find(e => e.match(/firebase:authUser/));
    const data = JSON.parse(localStorage.getItem(key));
    if (data == null) {
        replace({
            pathname: '/login',
            state: {
                nextPathname: nextState.location.pathname,
            },
        });
    }
}

module.exports = requireAuth;


================================================
FILE: src/app/utils/firebase.js
================================================
import firebase from 'firebase';
import { FIREBASE_CONFIG } from '../config';

export const firebaseApp = firebase.initializeApp(FIREBASE_CONFIG);
export const firebaseAuth = firebaseApp.auth();
export const firebaseDb = firebaseApp.database();

const FireBaseTools = {

  /**
   * Return an instance of a firebase auth provider based on the provider string.
   *
   * @param provider
   * @returns {firebase.auth.AuthProvider}
   */
    getProvider: (provider) => {
        switch (provider) {
        case 'email':
            return new firebase.auth.EmailAuthProvider();
        case 'facebook':
            return new firebase.auth.FacebookAuthProvider();
        case 'github':
            return new firebase.auth.GithubAuthProvider();
        case 'google':
            return new firebase.auth.GoogleAuthProvider();
        case 'twitter':
            return new firebase.auth.TwitterAuthProvider();
        default:
            throw new Error('Provider is not supported!!!');
        }
    },

  /**
   * Login with provider => p is provider "email", "facebook", "github", "google", or "twitter"
   * Uses Popup therefore provider must be an OAuth provider. EmailAuthProvider will throw an error
   *
   * @returns {any|!firebase.Thenable.<*>|firebase.Thenable<any>}
   */
    loginWithProvider: (p) => {
        const provider = FireBaseTools.getProvider(p);
        return firebaseAuth.signInWithPopup(provider).then(firebaseAuth.currentUser).catch(error => ({
            errorCode: error.code,
            errorMessage: error.message,
        }));
    },

  /**
   * Register a user with email and password
   *
   * @param user
   * @returns {any|!firebase.Thenable.<*>|firebase.Thenable<any>}
   */
    registerUser: user => firebaseAuth.createUserWithEmailAndPassword(user.email, user.password)
        .then(userInfo => userInfo)
        .catch(error => ({
            errorCode: error.code,
            errorMessage: error.message,
        })),

  /**
   * Sign the user out
   *
   * @returns {!firebase.Promise.<*>|firebase.Thenable<any>|firebase.Promise<any>|!firebase.Thenable.<*>}
   */
    logoutUser: () => firebaseAuth.signOut().then(() => ({
        success: 1,
        message: 'logout',
    })),

  /**
   * Retrieve the current user (Promise)
   * @returns {Promise}
   */
    fetchUser: () => new Promise((resolve, reject) => {
        const unsub = firebaseAuth.onAuthStateChanged((user) => {
            unsub();
            resolve(user);
        }, (error) => {
            reject(error);
        });
    }),

  /**
   * Log the user in using email and password
   *
   * @param user
   * @returns {any|!firebase.Thenable.<*>|firebase.Thenable<any>}
   */
    loginUser: user => firebaseAuth.signInWithEmailAndPassword(user.email, user.password)
        .then(userInfo => userInfo)
        .catch(error => ({
            errorCode: error.code,
            errorMessage: error.message,
        })),

  /**
   * Update a user's profile data
   *
   * @param u
   * @returns {!firebase.Promise.<*>|firebase.Thenable<any>|firebase.Promise<any>|!firebase.Thenable.<*>}
   */
    updateUserProfile: u => firebaseAuth.currentUser.updateProfile(u).then(() => firebaseAuth.currentUser, error => ({
        errorCode: error.code,
        errorMessage: error.message,
    })),

  /**
   * Reset the password given the specified email
   *
   * @param email {string}
   * @returns {!firebase.Promise.<*>|firebase.Thenable<any>|firebase.Promise<any>|!firebase.Thenable.<*>}
   */
    resetPasswordEmail: email => firebaseAuth.sendPasswordResetEmail(email).then(() => ({
        message: 'Email sent',
    }), error => ({
        errorCode: error.code,
        errorMessage: error.message,
    })),

  /**
   * Update the user's password with the given password
   *
   * @param newPassword {string}
   * @returns {!firebase.Promise.<*>|firebase.Thenable<any>|firebase.Promise<any>|!firebase.Thenable.<*>}
   */
    changePassword: newPassword => firebaseAuth.currentUser.updatePassword(newPassword).then(user => user, error => ({
        errorCode: error.code,
        errorMessage: error.message,
    })),

  /**
   * Send an account email verification message for the currently logged in user
   *
   * @returns {!firebase.Promise.<*>|firebase.Thenable<any>|firebase.Promise<any>|!firebase.Thenable.<*>}
   */
    sendEmailVerification: () => firebaseAuth.currentUser.sendEmailVerification().then(() => ({
        message: 'Email sent',
    }), error => ({
        errorCode: error.code,
        errorMessage: error.message,
    })),

  /**
   * Get the firebase database reference.
   *
   * @param path {!string|string}
   * @returns {!firebase.database.Reference|firebase.database.Reference}
   */
    getDatabaseReference: path => firebaseDb.ref(path),
};

export default FireBaseTools;


================================================
FILE: src/index.html
================================================
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
  <meta name="robots" content="index,follow"/>
  <meta name="googlebot" content="index,follow"/>
  <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
  <title>React, Redux & Firebase Boilerplate</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css"
        crossorigin="anonymous">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
        integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
        integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
</head>
<body>
<div class="react-root"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
        integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
        crossorigin="anonymous"></script>
</body>
</html>


================================================
FILE: test/components/app_test.js
================================================
import {renderComponent, expect} from '../test_helper';
import App from '../../src/app/components/app';

describe('App', () => {
  let component;

  beforeEach(() => {
    component = renderComponent(App);
  });

  it('renders something', () => {
    expect(component).to.exist;
  });
});


================================================
FILE: test/test_helper.js
================================================
import _$ from 'jquery';
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import jsdom from 'jsdom';
import chai, { expect } from 'chai';
import chaiJquery from 'chai-jquery';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import reducers from '../src/app/reducers';

global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.window = global.document.defaultView;
global.navigator = global.window.navigator;
const $ = _$(window);

chaiJquery(chai, chai.util, $);

function renderComponent(ComponentClass, props = {}, state = {}) {
  const componentInstance =  TestUtils.renderIntoDocument(
    <Provider store={createStore(reducers, state)}>
      <ComponentClass {...props} />
    </Provider>
  );

  return $(ReactDOM.findDOMNode(componentInstance));
}

$.fn.simulate = function(eventName, value) {
  if (value) {
    this.val(value);
  }
  TestUtils.Simulate[eventName](this[0]);
};

export {renderComponent, expect};


================================================
FILE: webpack/webpack-dev.config.js
================================================
module.exports = require('./webpack.config.js')({
  isProduction: false,
  devtool: 'cheap-module-source-map',
  jsFileName: 'app.js',
  cssFileName: 'app.css',
  port: 3000,
});


================================================
FILE: webpack/webpack-prod.config.js
================================================
module.exports = require('./webpack.config.js')({
  isProduction: true,
  devtool: 'source-map',
  jsFileName: 'app.[hash].js',
  cssFileName: 'app.[hash].css',
});


================================================
FILE: webpack/webpack.config.js
================================================
const Path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const Webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = (options) => {
  const ExtractSASS = new ExtractTextPlugin(`/styles/${options.cssFileName}`);

  const webpackConfig = {
    devtool: options.devtool,
    entry: [
      `webpack-dev-server/client?http://localhost:${+options.port}`,
      'webpack/hot/dev-server',
      Path.join(__dirname, '../src/app/index'),
    ],
    output: {
      path: Path.join(__dirname, '../dist'),
      filename: `/scripts/${options.jsFileName}`,
    },
    resolve: {
      extensions: ['', '.js', '.jsx'],
    },
    module: {
      loaders: [
        {test: /.jsx?$/, include: Path.join(__dirname, '../src/app'), loader: 'babel',},
        {test: /\.jsx?$/, exclude: /(node_modules|bower_components)/, loader: 'babel'},
        {test: /\.css$/, loader: 'style-loader!css-loader'},
        {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file"},
        {test: /\.(woff|woff2)$/, loader: "url?prefix=font/&limit=5000"},
        {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/octet-stream"},
        {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=image/svg+xml"}
      ],
    },
    plugins: [
      new Webpack.DefinePlugin({
        'process.env': {
          NODE_ENV: JSON.stringify(options.isProduction ? 'production' : 'development'),
        },
      }),
      new HtmlWebpackPlugin({
        template: Path.join(__dirname, '../src/index.html'),
      }),
    ],
  };

  if (options.isProduction) {
    webpackConfig.entry = [Path.join(__dirname, '../src/app/index')];

    webpackConfig.plugins.push(
      new Webpack.optimize.OccurenceOrderPlugin(),
      new Webpack.optimize.UglifyJsPlugin({
        compressor: {
          warnings: false,
        },
      }),
      ExtractSASS
    );

    webpackConfig.module.loaders.push({
      test: /\.scss$/,
      loader: ExtractSASS.extract(['css', 'sass']),
    });
  } else {
    webpackConfig.plugins.push(
      new Webpack.HotModuleReplacementPlugin()
    );

    webpackConfig.module.loaders.push({
      test: /\.scss$/,
      loaders: ['style', 'css', 'sass'],
    });

    webpackConfig.devServer = {
      contentBase: Path.join(__dirname, '../'),
      hot: true,
      port: options.port,
      inline: true,
      progress: true,
      historyApiFallback: true,
    };
  }

  return webpackConfig;
};


================================================
FILE: www.js
================================================
const express = require('express');
const app = express();

app.use(express.static('./'));
app.use(express.static('dist'));

app.get('*', (req, res) => {
    res.sendFile(`${__dirname}/dist/index.html`);
});

const port = process.env.PORT || 3000;

app.listen(port, () => {
    console.log('app listening on', port);
});
Download .txt
gitextract_tc2n1gmc/

├── .babelrc
├── .editorconfig
├── .eslintrc
├── .firebaserc
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── database.rules.json
├── firebase.json
├── jsconfig.json
├── package.json
├── src/
│   ├── app/
│   │   ├── actions/
│   │   │   ├── firebase_actions.js
│   │   │   ├── index.js
│   │   │   └── types.js
│   │   ├── bundle.scss
│   │   ├── components/
│   │   │   ├── app.jsx
│   │   │   ├── app.scss
│   │   │   ├── helpers/
│   │   │   │   └── loading.jsx
│   │   │   ├── index_home.jsx
│   │   │   └── user/
│   │   │       ├── change_password.jsx
│   │   │       ├── login.jsx
│   │   │       ├── logout.jsx
│   │   │       ├── profile.jsx
│   │   │       ├── register.jsx
│   │   │       └── reset_password.jsx
│   │   ├── config.js
│   │   ├── index.jsx
│   │   ├── reducers/
│   │   │   ├── firebase_user_reducer.js
│   │   │   └── index.js
│   │   ├── routes.jsx
│   │   └── utils/
│   │       ├── authenticated.js
│   │       └── firebase.js
│   └── index.html
├── test/
│   ├── components/
│   │   └── app_test.js
│   └── test_helper.js
├── webpack/
│   ├── webpack-dev.config.js
│   ├── webpack-prod.config.js
│   └── webpack.config.js
└── www.js
Download .txt
SYMBOL INDEX (65 symbols across 11 files)

FILE: src/app/actions/firebase_actions.js
  function loginWithProvider (line 13) | function loginWithProvider(provider) {
  function registerUser (line 20) | function registerUser(user) {
  function loginUser (line 27) | function loginUser(user) {
  function fetchUser (line 34) | function fetchUser() {
  function updateUser (line 40) | function updateUser(user) {
  function changePassword (line 47) | function changePassword(newPassword) {
  function resetPasswordEmail (line 54) | function resetPasswordEmail(email) {
  function logoutUser (line 61) | function logoutUser(user) {

FILE: src/app/actions/types.js
  constant LOGIN_WITH_PROVIDER_FIREBASE (line 4) | const LOGIN_WITH_PROVIDER_FIREBASE = 'LOGIN_WITH_PROVIDER_FIREBASE';
  constant REGISTER_FIREBASE_USER (line 5) | const REGISTER_FIREBASE_USER = 'REGISTER_FIREBASE_USER';
  constant LOGIN_FIREBASE_USER (line 6) | const LOGIN_FIREBASE_USER = 'LOGIN_FIREBASE_USER';
  constant FETCH_FIREBASE_USER (line 7) | const FETCH_FIREBASE_USER = 'FETCH_FIREBASE_USER';
  constant UPDATE_FIREBASE_USER (line 8) | const UPDATE_FIREBASE_USER = 'UPDATE_FIREBASE_USER';
  constant CHANGE_FIREBASE_USER_PASSWORD (line 9) | const CHANGE_FIREBASE_USER_PASSWORD = 'CHANGE_FIREBASE_USER_PASSWORD';
  constant FIREBASE_PASSWORD_RESET_EMAIL (line 10) | const FIREBASE_PASSWORD_RESET_EMAIL = 'FIREBASE_PASSWORD_RESET_EMAIL';
  constant LOGOUT_FIREBASE_USER (line 11) | const LOGOUT_FIREBASE_USER = 'LOGOUT_FIREBASE_USER';

FILE: src/app/components/app.jsx
  class App (line 10) | class App extends Component {
    method constructor (line 12) | constructor(props) {
    method _logOut (line 18) | _logOut() {
    method _read (line 25) | _read() {
    method _write (line 31) | _write() {
    method _renderUserMenu (line 35) | _renderUserMenu(currentUser) {
    method render (line 60) | render() {
  function mapDispatchToProps (line 96) | function mapDispatchToProps(dispatch) {
  function mapStateToProps (line 101) | function mapStateToProps(state) {

FILE: src/app/components/user/change_password.jsx
  class ChangePassword (line 6) | class ChangePassword extends Component {
    method constructor (line 8) | constructor(props) {
    method onFormSubmit (line 16) | onFormSubmit(event) {
    method render (line 34) | render() {
  function mapDispatchToProps (line 60) | function mapDispatchToProps(dispatch) {
  function mapStateToProps (line 64) | function mapStateToProps(state) {

FILE: src/app/components/user/login.jsx
  class UserLogin (line 8) | class UserLogin extends Component {
    method constructor (line 10) | constructor(props) {
    method onFormSubmit (line 19) | onFormSubmit(event) {
    method loginWithProvider (line 34) | loginWithProvider(provider) {
    method render (line 44) | render() {
  function mapDispatchToProps (line 103) | function mapDispatchToProps(dispatch) {
  function mapStateToProps (line 111) | function mapStateToProps(state) {

FILE: src/app/components/user/profile.jsx
  class UserProfile (line 11) | class UserProfile extends Component {
    method constructor (line 13) | constructor(props) {
    method onFormSubmit (line 22) | onFormSubmit(event) {
    method render (line 38) | render() {
  function mapDispatchToProps (line 74) | function mapDispatchToProps(dispatch) {
  function mapStateToProps (line 79) | function mapStateToProps(state) {

FILE: src/app/components/user/register.jsx
  class UserRegister (line 7) | class UserRegister extends Component {
    method constructor (line 8) | constructor(props) {
    method onFormSubmit (line 16) | onFormSubmit(event) {
    method render (line 32) | render() {
  function mapDispatchToProps (line 83) | function mapDispatchToProps(dispatch) {
  function mapStateToProps (line 89) | function mapStateToProps(state) {

FILE: src/app/components/user/reset_password.jsx
  class ResetPassword (line 6) | class ResetPassword extends Component {
    method constructor (line 7) | constructor(props) {
    method onFormSubmit (line 15) | onFormSubmit(event) {
    method render (line 27) | render() {
  function mapDispatchToProps (line 48) | function mapDispatchToProps(dispatch) {

FILE: src/app/reducers/firebase_user_reducer.js
  function loginWithProvider (line 47) | function loginWithProvider(provider) {
  function registerUser (line 51) | function registerUser(user) {
  function loginUser (line 55) | function loginUser(user) {
  function fetchUser (line 59) | function fetchUser() {
  function updateUser (line 63) | function updateUser(user) {
  function changePassword (line 67) | function changePassword(newPassword) {
  function resetPasswordEmail (line 71) | function resetPasswordEmail(email) {
  function logoutUser (line 75) | function logoutUser(user) {

FILE: src/app/utils/authenticated.js
  function requireAuth (line 1) | function requireAuth(nextState, replace) {

FILE: test/test_helper.js
  function renderComponent (line 19) | function renderComponent(ComponentClass, props = {}, state = {}) {
Condensed preview — 40 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (47K chars).
[
  {
    "path": ".babelrc",
    "chars": 48,
    "preview": "{\n  \"presets\": [\"react\", \"es2015\", \"stage-1\"]\n}\n"
  },
  {
    "path": ".editorconfig",
    "chars": 292,
    "preview": "# http://editorconfig.org\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_size = 2\nindent_style = space\ninsert_"
  },
  {
    "path": ".eslintrc",
    "chars": 279,
    "preview": "{\n  \"extends\": \"airbnb\",\n  \"parserOptions\": {\n    \"ecmaFeatures\": {\n      \"experimentalObjectRestSpread\": true\n    }\n  }"
  },
  {
    "path": ".firebaserc",
    "chars": 68,
    "preview": "{\n  \"projects\": {\n    \"default\": \"react-redux-firebase-d6283\"\n  }\n}\n"
  },
  {
    "path": ".gitignore",
    "chars": 620,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\n\n#\ndist\n\n# Runtime data\npids\n*.pid\n*.seed\n\n# Directory for instrumented libs generated "
  },
  {
    "path": ".travis.yml",
    "chars": 61,
    "preview": "language: node_js\nnode_js:\n  - \"node\"\n  - \"6\"\n  - \"5\"\n  - \"4\""
  },
  {
    "path": "LICENSE",
    "chars": 1078,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2016 btomashvili\n\nPermission is hereby granted, free of charge, to any person obtai"
  },
  {
    "path": "README.md",
    "chars": 2499,
    "preview": "# THIS PROJECT IS DEPRECATED IT'S NOT MAINTAINED ANYMORE!\n\n\n# React, Redux Firebase Boilerplate\n\n\n[![Build Status](https"
  },
  {
    "path": "database.rules.json",
    "chars": 252,
    "preview": "{\n  \"rules\": {\n    \".read\": false,\n    \".write\": false,\n    \"words\": {\n      \".read\": true,\n      \".write\": true\n    },\n"
  },
  {
    "path": "firebase.json",
    "chars": 202,
    "preview": "{\n  \"database\": {\n    \"rules\": \"database.rules.json\"\n  },\n  \"hosting\": {\n    \"public\": \"dist\",\n    \"rewrites\": [\n      {"
  },
  {
    "path": "jsconfig.json",
    "chars": 152,
    "preview": "{\n    \"compilerOptions\": {\n        \"target\": \"ES6\",\n         \"allowSyntheticDefaultImports\": true\n    },\n    \"exclude\": "
  },
  {
    "path": "package.json",
    "chars": 2580,
    "preview": "{\n  \"name\": \"react-redux-firebase-boilerplate\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Simple boilerplate for Reactjs w"
  },
  {
    "path": "src/app/actions/firebase_actions.js",
    "chars": 1090,
    "preview": "import {\n  LOGIN_WITH_PROVIDER_FIREBASE,\n  REGISTER_FIREBASE_USER,\n  LOGIN_FIREBASE_USER,\n  FETCH_FIREBASE_USER,\n  UPDAT"
  },
  {
    "path": "src/app/actions/index.js",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "src/app/actions/types.js",
    "chars": 561,
    "preview": "\n\n// / FIREBASE AUTH ACTIONS\nexport const LOGIN_WITH_PROVIDER_FIREBASE = 'LOGIN_WITH_PROVIDER_FIREBASE';\nexport const RE"
  },
  {
    "path": "src/app/bundle.scss",
    "chars": 27,
    "preview": "@import './components/app';"
  },
  {
    "path": "src/app/components/app.jsx",
    "chars": 3303,
    "preview": "import React, { Component } from 'react';\nimport { Link } from 'react-router';\nimport { connect } from 'react-redux';\nim"
  },
  {
    "path": "src/app/components/app.scss",
    "chars": 28,
    "preview": "body {\n  font-size: 16px;\n}\n"
  },
  {
    "path": "src/app/components/helpers/loading.jsx",
    "chars": 160,
    "preview": "import React from 'react';\n\n\nconst Loading = () => {\n    return (\n    <div className=\"col-md-4\">\n      Loading ....\n    "
  },
  {
    "path": "src/app/components/index_home.jsx",
    "chars": 107,
    "preview": "import React from 'react';\n\nexport default () => {\n  return <div> Home Page of our application! </div>;\n};\n"
  },
  {
    "path": "src/app/components/user/change_password.jsx",
    "chars": 2016,
    "preview": "import React, { Component } from 'react';\nimport { connect } from 'react-redux';\nimport { bindActionCreators } from 'red"
  },
  {
    "path": "src/app/components/user/login.jsx",
    "chars": 3969,
    "preview": "import React, { Component } from 'react';\nimport { browserHistory, Link } from 'react-router';\nimport { connect } from '"
  },
  {
    "path": "src/app/components/user/logout.jsx",
    "chars": 144,
    "preview": "import React from 'react';\n\n\nexport default () => (\n    <form id=\"frmLogout\" role=\"form\">\n        <h2>You are logged out"
  },
  {
    "path": "src/app/components/user/profile.jsx",
    "chars": 2739,
    "preview": "import React, { Component } from 'react';\nimport { connect } from 'react-redux';\nimport { bindActionCreators } from 'red"
  },
  {
    "path": "src/app/components/user/register.jsx",
    "chars": 3384,
    "preview": "import React, { Component } from 'react';\nimport { browserHistory } from 'react-router';\nimport { connect } from 'react-"
  },
  {
    "path": "src/app/components/user/reset_password.jsx",
    "chars": 1671,
    "preview": "import React, { Component } from 'react';\nimport { connect } from 'react-redux';\nimport { bindActionCreators } from 'red"
  },
  {
    "path": "src/app/config.js",
    "chars": 431,
    "preview": "module.exports = {\n\n  // Change this to your firebase configuration! (Add Firebase to your web app)\n    FIREBASE_CONFIG:"
  },
  {
    "path": "src/app/index.jsx",
    "chars": 967,
    "preview": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Provider } from 'react-redux';\nimport { createStor"
  },
  {
    "path": "src/app/reducers/firebase_user_reducer.js",
    "chars": 1573,
    "preview": "import FireBaseTools from '../utils/firebase';\nimport {\n  LOGIN_WITH_PROVIDER_FIREBASE,\n  REGISTER_FIREBASE_USER,\n  LOGI"
  },
  {
    "path": "src/app/reducers/index.js",
    "chars": 210,
    "preview": "import { combineReducers } from 'redux';\nimport FireBaseUserReducer from './firebase_user_reducer';\n\nconst rootReducer ="
  },
  {
    "path": "src/app/routes.jsx",
    "chars": 907,
    "preview": "import React from 'react';\nimport { Route, IndexRoute } from 'react-router';\nimport App from './components/app';\n\nimport"
  },
  {
    "path": "src/app/utils/authenticated.js",
    "chars": 402,
    "preview": "function requireAuth(nextState, replace) {\n    const key = Object.keys(localStorage).find(e => e.match(/firebase:authUse"
  },
  {
    "path": "src/app/utils/firebase.js",
    "chars": 4817,
    "preview": "import firebase from 'firebase';\nimport { FIREBASE_CONFIG } from '../config';\n\nexport const firebaseApp = firebase.initi"
  },
  {
    "path": "src/index.html",
    "chars": 1287,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\"/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-sca"
  },
  {
    "path": "test/components/app_test.js",
    "chars": 289,
    "preview": "import {renderComponent, expect} from '../test_helper';\nimport App from '../../src/app/components/app';\n\ndescribe('App',"
  },
  {
    "path": "test/test_helper.js",
    "chars": 1037,
    "preview": "import _$ from 'jquery';\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport TestUtils from 'react-addon"
  },
  {
    "path": "webpack/webpack-dev.config.js",
    "chars": 179,
    "preview": "module.exports = require('./webpack.config.js')({\n  isProduction: false,\n  devtool: 'cheap-module-source-map',\n  jsFileN"
  },
  {
    "path": "webpack/webpack-prod.config.js",
    "chars": 165,
    "preview": "module.exports = require('./webpack.config.js')({\n  isProduction: true,\n  devtool: 'source-map',\n  jsFileName: 'app.[has"
  },
  {
    "path": "webpack/webpack.config.js",
    "chars": 2519,
    "preview": "const Path = require('path');\nconst HtmlWebpackPlugin = require('html-webpack-plugin');\nconst Webpack = require('webpack"
  },
  {
    "path": "www.js",
    "chars": 321,
    "preview": "const express = require('express');\nconst app = express();\n\napp.use(express.static('./'));\napp.use(express.static('dist'"
  }
]

About this extraction

This page contains the full source code of the btomashvili/react-redux-firebase-boilerplate GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 40 files (41.4 KB), approximately 10.9k tokens, and a symbol index with 65 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!