Skip to content

Commit

Permalink
Merge pull request #4 from IS3106-T07/hansel
Browse files Browse the repository at this point in the history
Update to CRA-v2, and new project structure
  • Loading branch information
quanle1994 authored Oct 26, 2018
2 parents 2bff5f2 + 9f0b21c commit e9f4607
Show file tree
Hide file tree
Showing 34 changed files with 1,205 additions and 74 deletions.
1 change: 0 additions & 1 deletion .env

This file was deleted.

4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
# dependencies
/node_modules

# IDE
/.idea

# testing
/coverage

Expand All @@ -19,3 +22,4 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
123 changes: 87 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,94 @@
# Frontend Setup
> Instructions to install dependencies and run frontend development environment.
## Project Files
This is our basic file structure, including `build/`, `public/` and `src/`.
```
├── build
│   └── ...generated static resources: css, js, media
├── public
│   └── ...favicon.ico, index.html, manifest.json
├── src
│ └── ...development files
├── .gitignore
├── package.json (dependencies, scripts, configuration)
└── README.md
```
## Development
For development, `src/` contains the main assets. There are `components/`, `resources/`, redux-based `actions/`, `constants/`, `reducers/` and `services/`.

### Directory
.
├── create-react-app # For installing dependencies, you can delete after install
└── frontend # Actual development environment
├── other files... # Stores App.js, components/, etc..
└── (to be updated)
**Note**: each folder contains a file called `index.js`. This helps to shorten import statements, and the decision to include these is for convenience.

### Install Create-React-App (only for dependencies)
Link: /~https://github.com/IS3106-T07/create-react-app
```
/ ...
└── src
├── actions
│   ├── ...actions.js
│   └── index.js
├── components
│ ├── css
│   │   └── ...example.module.css
│   ├── App.js
│   ├── PrivateRoute.js
│   └── ...PageComponents.js
├── constants
│   ├── ...constants.js
│   └── index.js
├── reducers
│   ├── ...reducer.js
│   └── index.js
├── resources
│   └── (images)
├── services
│ ├── ...service.js
│ └── index.js
└ ...
```

git clone /~https://github.com/IS3106-T07/create-react-app
cd create-react-app
npm install
And `helpers/`, `index.html` and `index.js`.
```
...
├── helpers
│   ├── auth-header.js
│   ├── fake-backend.js
│   ├── history.js
│   ├── index.js
│   ├── serviceWorker.js
│   └── store.js
├── index.html
└── index.js
```

### Install Frontend
Link: Current Page
## Using this project
The development server runs on `PORT 8000`. See *scripts* in `package.json` to change.
Configure *apiUrl* at `src/index.js`. Default value: http://localhost:3000.

cd ..
git clone /~https://github.com/IS3106-T07/frontend
cd frontend
npm install
**Note**: `HTTPS` is required for service workers.

Run in **development**
```
npm install
npm start
HTTPS=true npm start // Linux, macOS (bash)
set HTTPS=true&&npm start // Windows (cmd.exe)
($env:HTTPS = $true) -and (npm start) // Windows (powershell)
```
Run in **production**
```
npm install
npm run build
serve -s build
```
Run **tests**
```
npm build
npm run test
```

### Testing
npm test
## Creating a component
```
// todo Guide
```

### Run
npm start

Running at http://localhost:3003 (and at specified IP network address, e.g. 192.168.1.40:3003)

# FAQ
> Frequently asked questions.
### Q. I'm stuck at registry config, on install. How to proceed?
Set config manually.

npm config set registry="http://registry.npmjs.org"

### Q. Where is the PWA Setup Guide?
See MANUAL.md.
This brings us to the end of project-specific documentation.
48 changes: 37 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,44 @@
"name": "frontend",
"version": "0.1.0",
"private": true,
"devDependencies": {
"react-router-dom": "^4.4.0-alpha.1",
"react-scripts": "1.1.5"
"license": "MIT",
"scripts": {
"start": "PORT=8000 react-scripts start export",
"build": "react-scripts build",
"test": "react-scripts test"
},
"eslintConfig": {
"extends": "react-app"
},
"dependencies": {
"react": "^16.5.1",
"react-dom": "^16.5.1"
"config": "^2.0.1",
"history": "^4.6.3",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-redux": "^5.0.5",
"react-router-dom": "^4.1.2",
"redux": "^3.7.2",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.2.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
"devDependencies": {
"babel-core": "^6.21.0",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-3": "^6.24.1",
"css-loader": "^1.0.0",
"html-webpack-plugin": "^2.26.0",
"path": "^0.12.7",
"react-scripts": "2.0.5",
"style-loader": "^0.23.0",
"url-loader": "^1.1.1",
"webpack-cli": "^3.1.2"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"homepage": "./"
}
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<title>Public</title>
</head>
<body>
<noscript>
Expand Down
19 changes: 19 additions & 0 deletions src/actions/alert.actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { alertConstants } from '../constants';

export const alertActions = {
success,
error,
clear
};

function success(message) {
return { type: alertConstants.SUCCESS, message };
}

function error(message) {
return { type: alertConstants.ERROR, message };
}

function clear() {
return { type: alertConstants.CLEAR };
}
2 changes: 2 additions & 0 deletions src/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './alert.actions';
export * from './user.actions';
94 changes: 94 additions & 0 deletions src/actions/user.actions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { userConstants } from '../constants';
import { userService, history } from '../helpers';
import { alertActions } from './';

export const userActions = {
login,
logout,
register,
getAll,
delete: _delete
};

function login(email, password) {
return dispatch => {
dispatch(request({ email }));
userService.login(email, password)
.then(
user => {
dispatch(success(user));
history.push('/');
},
error => {
dispatch(failure(error.toString()));
console.log(error);
dispatch(alertActions.error(error.toString()));
}
);
};

function request(user) { return { type: userConstants.LOGIN_REQUEST, user } }
function success(user) { return { type: userConstants.LOGIN_SUCCESS, user } }
function failure(error) { return { type: userConstants.LOGIN_FAILURE, error } }
}

function logout() {
userService.logout();
return { type: userConstants.LOGOUT };
}

function register(user) {
return dispatch => {
dispatch(request(user));

userService.register(user)
.then(
user => {
dispatch(success());
history.push('/login');
dispatch(alertActions.success('Registration successful'));
},
error => {
dispatch(failure(error.toString()));
dispatch(alertActions.error(error.toString()));
}
);
};

function request(user) { return { type: userConstants.REGISTER_REQUEST, user } }
function success(user) { return { type: userConstants.REGISTER_SUCCESS, user } }
function failure(error) { return { type: userConstants.REGISTER_FAILURE, error } }
}

function getAll() {
return dispatch => {
dispatch(request());

userService.getAll()
.then(
users => dispatch(success(users)),
error => dispatch(failure(error.toString()))
);
};

function request() { return { type: userConstants.GETALL_REQUEST } }
function success(users) { return { type: userConstants.GETALL_SUCCESS, users } }
function failure(error) { return { type: userConstants.GETALL_FAILURE, error } }
}

// prefixed function name with underscore because delete is a reserved word in javascript
function _delete(id) {
return dispatch => {
dispatch(request(id));

userService.delete(id)
.then(
user => dispatch(success(id)),
error => dispatch(failure(id, error.toString()))
);
};

function request(id) { return { type: userConstants.DELETE_REQUEST, id } }
function success(id) { return { type: userConstants.DELETE_SUCCESS, id } }
function failure(id, error) { return { type: userConstants.DELETE_FAILURE, id, error } }
}
54 changes: 54 additions & 0 deletions src/components/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import { Router, Route } from 'react-router-dom';
import { connect } from 'react-redux';

import { history } from '../helpers';
import { alertActions } from '../actions';
import { PrivateRoute } from './PrivateRoute';
import { HomePage } from './HomePage';
import { LoginPage } from './LoginPage';
import { RegisterPage } from './RegisterPage';

class App extends React.Component {
constructor(props) {
super(props);

const { dispatch } = this.props;
history.listen((location, action) => {
// clear alert on location change
dispatch(alertActions.clear());
});
}

render() {
const { alert } = this.props;
return (
<div className="jumbotron">
<div className="container">
<div className="col-sm-8 col-sm-offset-2">
{alert.message &&
<div className={`alert ${alert.type}`}>{alert.message}</div>
}
<Router history={history}>
<div>
<PrivateRoute exact path="/" component={HomePage} />
<Route path="/login" component={LoginPage} />
<Route path="/register" component={RegisterPage} />
</div>
</Router>
</div>
</div>
</div>
);
}
}

function mapStateToProps(state) {
const { alert } = state;
return {
alert
};
}

const connectedApp = connect(mapStateToProps)(App);
export { connectedApp as App };
Loading

0 comments on commit e9f4607

Please sign in to comment.