diff --git a/05 SimpleApp_Navigation/.babelrc b/05 SimpleApp_Navigation/.babelrc new file mode 100644 index 0000000..03dfd13 --- /dev/null +++ b/05 SimpleApp_Navigation/.babelrc @@ -0,0 +1,10 @@ +{ + "presets": [ + [ + "env", + { + "modules": false + } + ] + ] +} diff --git a/05 SimpleApp_Navigation/package.json b/05 SimpleApp_Navigation/package.json new file mode 100644 index 0000000..150cf5a --- /dev/null +++ b/05 SimpleApp_Navigation/package.json @@ -0,0 +1,45 @@ +{ + "name": "sample", + "version": "1.0.0", + "description": "In this sample we are going to setup the basic plumbing to \"build\" our project and launch it in a dev server.", + "main": "index.js", + "scripts": { + "start": "webpack-dev-server --mode development --inline --hot --open", + "build": "webpack --mode development", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "@types/react": "^16.3.12", + "@types/react-dom": "^16.0.5", + "@types/react-redux": "^5.0.16", + "@types/react-router": "^3.0.15", + "@types/react-router-redux": "^4.0.51", + "@types/redux-thunk": "^2.1.0", + "awesome-typescript-loader": "^5.0.0", + "babel-core": "^6.26.0", + "babel-preset-env": "^1.6.1", + "css-loader": "^0.28.11", + "file-loader": "^1.1.11", + "html-webpack-plugin": "^3.2.0", + "mini-css-extract-plugin": "^0.4.0", + "style-loader": "^0.20.3", + "typescript": "^2.8.1", + "url-loader": "^1.0.1", + "webpack": "^4.5.0", + "webpack-cli": "^2.0.14", + "webpack-dev-server": "^3.1.0" + }, + "dependencies": { + "babel-polyfill": "^6.26.0", + "bootstrap": "^4.1.0", + "react": "^16.3.2", + "react-dom": "^16.3.2", + "react-redux": "^5.0.7", + "react-router": "^3.2.1", + "react-router-redux": "^4.0.8", + "redux": "^4.0.0", + "redux-thunk": "^2.2.0" + } +} diff --git a/06 SimpleApp_Navigation/readme.md b/05 SimpleApp_Navigation/readme.md similarity index 99% rename from 06 SimpleApp_Navigation/readme.md rename to 05 SimpleApp_Navigation/readme.md index ce87b0f..feebd70 100644 --- a/06 SimpleApp_Navigation/readme.md +++ b/05 SimpleApp_Navigation/readme.md @@ -1,4 +1,4 @@ -# 06 Simple App +# 05 Simple App This sample series takes as starting point _02 Change Name_ @@ -323,7 +323,8 @@ export const App = () => { - import {NameEditContainer} from './nameEditContainer'; + import { Link } from 'react-router' - export const App = (props: { children? }) => { +- export const App = () => { ++ export const App = (props: { children? }) => { return (
- diff --git a/05 SimpleApp_Navigation/src/app.tsx b/05 SimpleApp_Navigation/src/app.tsx new file mode 100644 index 0000000..816d2b6 --- /dev/null +++ b/05 SimpleApp_Navigation/src/app.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; +import { Link } from 'react-router'; + +export const App = (props: { children?}) => { + return ( +
+
+ Links: + {' '} + Login + {' '} + Student List + {' '} + Student Detail +
+
{props.children}
+
+ ); +} + \ No newline at end of file diff --git a/06 SimpleApp_Navigation/src/common/actionsEnums.ts b/05 SimpleApp_Navigation/src/common/actionsEnums.ts similarity index 63% rename from 06 SimpleApp_Navigation/src/common/actionsEnums.ts rename to 05 SimpleApp_Navigation/src/common/actionsEnums.ts index f4ef099..960938f 100644 --- a/06 SimpleApp_Navigation/src/common/actionsEnums.ts +++ b/05 SimpleApp_Navigation/src/common/actionsEnums.ts @@ -1,4 +1,5 @@ + export const actionsEnums = { USERPROFILE_UPDATE_EDITING_LOGIN: 'USERPROFILE_UPDATE_EDITING_LOGIN', - USERPROFILE_PERFORM_LOGIN : 'USERPROFILE_PERFORM_LOGIN' -} + USERPROFILE_PERFORM_LOGIN: 'USERPROFILE_PERFORM_LOGIN' +} \ No newline at end of file diff --git a/06 SimpleApp_Navigation/src/index.html b/05 SimpleApp_Navigation/src/index.html similarity index 53% rename from 06 SimpleApp_Navigation/src/index.html rename to 05 SimpleApp_Navigation/src/index.html index 4b32a83..5466c9b 100644 --- a/06 SimpleApp_Navigation/src/index.html +++ b/05 SimpleApp_Navigation/src/index.html @@ -5,8 +5,10 @@ -

Sample app

-
+
+

Sample app

+
+
- + \ No newline at end of file diff --git a/06 SimpleApp_Navigation/src/main.tsx b/05 SimpleApp_Navigation/src/main.tsx similarity index 58% rename from 06 SimpleApp_Navigation/src/main.tsx rename to 05 SimpleApp_Navigation/src/main.tsx index 8fd08f3..069197a 100644 --- a/06 SimpleApp_Navigation/src/main.tsx +++ b/05 SimpleApp_Navigation/src/main.tsx @@ -1,40 +1,39 @@ import * as React from 'react'; import * as ReactDOM from 'react-dom'; -import { createStore, applyMiddleware, compose } from 'redux'; import { Router, Route, IndexRoute, hashHistory } from 'react-router'; -import { syncHistoryWithStore } from 'react-router-redux' +import { syncHistoryWithStore } from 'react-router-redux'; +import { createStore, applyMiddleware, compose } from 'redux'; import reduxThunk from 'redux-thunk'; import { Provider } from 'react-redux'; -import {reducers} from './reducers' -import {App} from './app'; -import {LoginContainer} from './pages/login'; -import {StudentListContainer} from './pages/student-list'; -import {StudentDetailContainer} from './pages/student-detail'; - +import { reducers } from './reducers'; +import { App } from './app'; +import { LoginContainer } from './pages/login'; +import { StudentListContainer } from './pages/student-list'; +import { StudentDetailContainer } from './pages/student-detail'; +const nonTypedWindow: any = window; let store = createStore( reducers, compose( applyMiddleware(reduxThunk), window['devToolsExtension'] ? window['devToolsExtension']() : f => f - ) + ) ); const history = syncHistoryWithStore(hashHistory, store); ReactDOM.render( - +
- - - - + + + +
-
, - document.getElementById('root') -); - +
+ , + document.getElementById('root')); \ No newline at end of file diff --git a/05 SimpleApp_Navigation/src/model/index.ts b/05 SimpleApp_Navigation/src/model/index.ts new file mode 100644 index 0000000..af2173e --- /dev/null +++ b/05 SimpleApp_Navigation/src/model/index.ts @@ -0,0 +1,3 @@ +export * from './login'; +export * from './loginResponse'; +export * from './userProfile'; \ No newline at end of file diff --git a/05 SimpleApp_Navigation/src/model/login.ts b/05 SimpleApp_Navigation/src/model/login.ts new file mode 100644 index 0000000..3bc4f31 --- /dev/null +++ b/05 SimpleApp_Navigation/src/model/login.ts @@ -0,0 +1,9 @@ +export class LoginEntity { + login : string; + password : string; + + public constructor() { + this.login = ''; + this.password = ''; + } + } \ No newline at end of file diff --git a/06 SimpleApp_Navigation/src/model/loginResponse.ts b/05 SimpleApp_Navigation/src/model/loginResponse.ts similarity index 100% rename from 06 SimpleApp_Navigation/src/model/loginResponse.ts rename to 05 SimpleApp_Navigation/src/model/loginResponse.ts diff --git a/05 SimpleApp_Navigation/src/model/userProfile.ts b/05 SimpleApp_Navigation/src/model/userProfile.ts new file mode 100644 index 0000000..6112f66 --- /dev/null +++ b/05 SimpleApp_Navigation/src/model/userProfile.ts @@ -0,0 +1,4 @@ +export class UserProfile { + fullname : string; + role : string; + } \ No newline at end of file diff --git a/05 SimpleApp_Navigation/src/pages/login/actions/loginRequest.ts b/05 SimpleApp_Navigation/src/pages/login/actions/loginRequest.ts new file mode 100644 index 0000000..1659353 --- /dev/null +++ b/05 SimpleApp_Navigation/src/pages/login/actions/loginRequest.ts @@ -0,0 +1,28 @@ +import { actionsEnums } from '../../../common/actionsEnums'; +import { LoginResponse } from '../../../model/loginResponse'; +import { LoginEntity } from '../../../model/login'; +import { loginApi } from '../../../rest-api/loginApi'; +import { hashHistory } from 'react-router'; + +export const loginRequestStartedAction = (login: LoginEntity) => { + return function (dispatcher) { + const promise = loginApi.login(login); + promise.then( + data => { + dispatcher(loginRequestCompletedAction(data)); + // This is not ideal to have it here, maybe move it to middleware? + if (data.succeeded == true) { + hashHistory.push('/student-list'); + } + } + ); + return promise; + } +} + +const loginRequestCompletedAction = (loginResponse: LoginResponse) => { + return { + type: actionsEnums.USERPROFILE_PERFORM_LOGIN, + payload: loginResponse + } +} \ No newline at end of file diff --git a/05 SimpleApp_Navigation/src/pages/login/actions/updateEditingLogin.ts b/05 SimpleApp_Navigation/src/pages/login/actions/updateEditingLogin.ts new file mode 100644 index 0000000..5dd8d4a --- /dev/null +++ b/05 SimpleApp_Navigation/src/pages/login/actions/updateEditingLogin.ts @@ -0,0 +1,9 @@ +import { actionsEnums } from '../../../common/actionsEnums'; +import { LoginEntity } from '../../../model/login'; + +export const updateEditingLogin = (loginInfo: LoginEntity) => { + return { + type: actionsEnums.USERPROFILE_UPDATE_EDITING_LOGIN, + payload: loginInfo + } +} \ No newline at end of file diff --git a/06 SimpleApp_Navigation/src/pages/login/components/form.tsx b/05 SimpleApp_Navigation/src/pages/login/components/form.tsx similarity index 99% rename from 06 SimpleApp_Navigation/src/pages/login/components/form.tsx rename to 05 SimpleApp_Navigation/src/pages/login/components/form.tsx index ea54bda..c9a5cda 100644 --- a/06 SimpleApp_Navigation/src/pages/login/components/form.tsx +++ b/05 SimpleApp_Navigation/src/pages/login/components/form.tsx @@ -32,4 +32,4 @@ export const Form = (props: Props) => {
); -} +} \ No newline at end of file diff --git a/06 SimpleApp_Navigation/src/pages/login/components/header.tsx b/05 SimpleApp_Navigation/src/pages/login/components/header.tsx similarity index 91% rename from 06 SimpleApp_Navigation/src/pages/login/components/header.tsx rename to 05 SimpleApp_Navigation/src/pages/login/components/header.tsx index f2ff3c8..eb554ad 100644 --- a/06 SimpleApp_Navigation/src/pages/login/components/header.tsx +++ b/05 SimpleApp_Navigation/src/pages/login/components/header.tsx @@ -1,9 +1,9 @@ import * as React from "react" export const Header = () => { - return ( + return (

Please sign in

); -} +} \ No newline at end of file diff --git a/05 SimpleApp_Navigation/src/pages/login/index.ts b/05 SimpleApp_Navigation/src/pages/login/index.ts new file mode 100644 index 0000000..5b5b012 --- /dev/null +++ b/05 SimpleApp_Navigation/src/pages/login/index.ts @@ -0,0 +1 @@ +export { LoginContainer } from './loginContainer'; \ No newline at end of file diff --git a/05 SimpleApp_Navigation/src/pages/login/login.tsx b/05 SimpleApp_Navigation/src/pages/login/login.tsx new file mode 100644 index 0000000..e24b253 --- /dev/null +++ b/05 SimpleApp_Navigation/src/pages/login/login.tsx @@ -0,0 +1,28 @@ +import * as React from 'react'; +import { Header } from './components/header'; +import { Form } from './components/form'; +import { LoginEntity } from '../../model/login'; + +interface Props { + loginInfo: LoginEntity; + updateLoginInfo: (loginInfo: LoginEntity) => void; + performLogin: (loginInfo: LoginEntity) => void; +} + +export const LoginComponent = (props: Props) => { + return ( +
+
+
+
+
+
props.performLogin(props.loginInfo)} + /> +
+
+
+
+ ) +} \ No newline at end of file diff --git a/05 SimpleApp_Navigation/src/pages/login/loginContainer.tsx b/05 SimpleApp_Navigation/src/pages/login/loginContainer.tsx new file mode 100644 index 0000000..289f890 --- /dev/null +++ b/05 SimpleApp_Navigation/src/pages/login/loginContainer.tsx @@ -0,0 +1,23 @@ +import { connect } from 'react-redux'; +import { LoginComponent } from './login'; +import { LoginEntity } from '../../model/login'; +import { updateEditingLogin } from './actions/updateEditingLogin'; +import { loginRequestStartedAction } from './actions/loginRequest'; + +const mapStateToProps = (state) => { + return { + loginInfo: state.sessionReducer.editingLogin + } +} + +const mapDispatchToProps = (dispatch) => { + return { + updateLoginInfo: (loginInfo: LoginEntity) => dispatch(updateEditingLogin(loginInfo)), + performLogin: (loginInfo: LoginEntity) => dispatch(loginRequestStartedAction(loginInfo)) + } +} + +export const LoginContainer = connect( + mapStateToProps + , mapDispatchToProps +)(LoginComponent); \ No newline at end of file diff --git a/05 SimpleApp_Navigation/src/pages/student-detail/index.ts b/05 SimpleApp_Navigation/src/pages/student-detail/index.ts new file mode 100644 index 0000000..e067ac3 --- /dev/null +++ b/05 SimpleApp_Navigation/src/pages/student-detail/index.ts @@ -0,0 +1 @@ +export {StudentDetailContainer} from './studentDetailContainer'; diff --git a/06 SimpleApp_Navigation/src/pages/student-detail/studentDetail.tsx b/05 SimpleApp_Navigation/src/pages/student-detail/studentDetail.tsx similarity index 98% rename from 06 SimpleApp_Navigation/src/pages/student-detail/studentDetail.tsx rename to 05 SimpleApp_Navigation/src/pages/student-detail/studentDetail.tsx index 97d23c0..926f2d0 100644 --- a/06 SimpleApp_Navigation/src/pages/student-detail/studentDetail.tsx +++ b/05 SimpleApp_Navigation/src/pages/student-detail/studentDetail.tsx @@ -4,4 +4,4 @@ export const StudentDetailComponent = () => { return (

I'm the StudentDetail page

) -} +} \ No newline at end of file diff --git a/06 SimpleApp_Navigation/src/pages/student-detail/studentDetailContainer.tsx b/05 SimpleApp_Navigation/src/pages/student-detail/studentDetailContainer.tsx similarity index 57% rename from 06 SimpleApp_Navigation/src/pages/student-detail/studentDetailContainer.tsx rename to 05 SimpleApp_Navigation/src/pages/student-detail/studentDetailContainer.tsx index de5e682..42769d1 100644 --- a/06 SimpleApp_Navigation/src/pages/student-detail/studentDetailContainer.tsx +++ b/05 SimpleApp_Navigation/src/pages/student-detail/studentDetailContainer.tsx @@ -2,8 +2,8 @@ import { connect } from 'react-redux'; import { StudentDetailComponent } from './studentDetail'; const mapStateToProps = (state) => { - return { - } + return { + } } const mapDispatchToProps = (dispatch) => { @@ -12,6 +12,6 @@ const mapDispatchToProps = (dispatch) => { } export const StudentDetailContainer = connect( - mapStateToProps - ,mapDispatchToProps - )(StudentDetailComponent); + mapStateToProps + , mapDispatchToProps +)(StudentDetailComponent); \ No newline at end of file diff --git a/05 SimpleApp_Navigation/src/pages/student-list/index.ts b/05 SimpleApp_Navigation/src/pages/student-list/index.ts new file mode 100644 index 0000000..f5a5451 --- /dev/null +++ b/05 SimpleApp_Navigation/src/pages/student-list/index.ts @@ -0,0 +1 @@ +export {StudentListContainer} from './studentListContainer'; \ No newline at end of file diff --git a/06 SimpleApp_Navigation/src/pages/student-list/studentList.tsx b/05 SimpleApp_Navigation/src/pages/student-list/studentList.tsx similarity index 55% rename from 06 SimpleApp_Navigation/src/pages/student-list/studentList.tsx rename to 05 SimpleApp_Navigation/src/pages/student-list/studentList.tsx index 372bdfc..811e4d9 100644 --- a/06 SimpleApp_Navigation/src/pages/student-list/studentList.tsx +++ b/05 SimpleApp_Navigation/src/pages/student-list/studentList.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; export const StudentListComponent = () => { - return ( -

I'm the StudentList page

- ) -} + return ( +

I'm the StudentList page

+ ) +} \ No newline at end of file diff --git a/06 SimpleApp_Navigation/src/pages/student-list/studentListContainer.tsx b/05 SimpleApp_Navigation/src/pages/student-list/studentListContainer.tsx similarity index 57% rename from 06 SimpleApp_Navigation/src/pages/student-list/studentListContainer.tsx rename to 05 SimpleApp_Navigation/src/pages/student-list/studentListContainer.tsx index bcb8b5d..b74fa88 100644 --- a/06 SimpleApp_Navigation/src/pages/student-list/studentListContainer.tsx +++ b/05 SimpleApp_Navigation/src/pages/student-list/studentListContainer.tsx @@ -2,8 +2,8 @@ import { connect } from 'react-redux'; import { StudentListComponent } from './studentList'; const mapStateToProps = (state) => { - return { - } + return { + } } const mapDispatchToProps = (dispatch) => { @@ -12,6 +12,6 @@ const mapDispatchToProps = (dispatch) => { } export const StudentListContainer = connect( - mapStateToProps - ,mapDispatchToProps - )(StudentListComponent); + mapStateToProps + , mapDispatchToProps +)(StudentListComponent); \ No newline at end of file diff --git a/05 SimpleApp_Navigation/src/reducers/index.ts b/05 SimpleApp_Navigation/src/reducers/index.ts new file mode 100644 index 0000000..d7fbd18 --- /dev/null +++ b/05 SimpleApp_Navigation/src/reducers/index.ts @@ -0,0 +1,8 @@ +import { combineReducers} from 'redux'; +import { sessionReducer } from './session'; +import { routerReducer, RouterState } from 'react-router-redux'; + +export const reducers = combineReducers({ + sessionReducer, + routing: routerReducer +}); diff --git a/05 SimpleApp_Navigation/src/reducers/session.ts b/05 SimpleApp_Navigation/src/reducers/session.ts new file mode 100644 index 0000000..6da4917 --- /dev/null +++ b/05 SimpleApp_Navigation/src/reducers/session.ts @@ -0,0 +1,42 @@ +import { actionsEnums } from '../common/actionsEnums'; +import { UserProfile } from '../model/userProfile'; +import { LoginResponse } from '../model/loginResponse'; +import { LoginEntity } from '../model/login'; + +class SessionState { + isUserLoggedIn: boolean; + userProfile: UserProfile; + editingLogin: LoginEntity; + + public constructor() { + this.isUserLoggedIn = false; + this.userProfile = new UserProfile(); + this.editingLogin = new LoginEntity(); + } +} + +export const sessionReducer = (state: SessionState = new SessionState(), action) => { + switch (action.type) { + case actionsEnums.USERPROFILE_PERFORM_LOGIN: + return handlePerformLogin(state, action.payload); + case actionsEnums.USERPROFILE_UPDATE_EDITING_LOGIN: + return handleUpdateEditingLogin(state, action.payload); + } + return state; +}; + + +const handlePerformLogin = (state: SessionState, payload: LoginResponse) => { + return { + ...state, + isUserLoggedIn: payload.succeeded, + userProfile: payload.userProfile + }; +} + +const handleUpdateEditingLogin = (state: SessionState, payload: LoginEntity) => { + return { + ...state, + editingLogin: payload + }; +} \ No newline at end of file diff --git a/06 SimpleApp_Navigation/src/rest-api/loginApi.ts b/05 SimpleApp_Navigation/src/rest-api/loginApi.ts similarity index 71% rename from 06 SimpleApp_Navigation/src/rest-api/loginApi.ts rename to 05 SimpleApp_Navigation/src/rest-api/loginApi.ts index 3924d98..e283fa1 100644 --- a/06 SimpleApp_Navigation/src/rest-api/loginApi.ts +++ b/05 SimpleApp_Navigation/src/rest-api/loginApi.ts @@ -1,6 +1,4 @@ -import {LoginEntity} from '../model/login'; -import {UserProfile} from '../model/userProfile'; -import {LoginResponse} from '../model/loginResponse'; +import {LoginEntity,UserProfile,LoginResponse} from '../model'; class LoginApi { login(loginInfo : LoginEntity) : Promise { @@ -18,4 +16,4 @@ class LoginApi { } } -export const loginApi = new LoginApi(); +export const loginApi = new LoginApi(); \ No newline at end of file diff --git a/06 SimpleApp_Navigation/tsconfig.json b/05 SimpleApp_Navigation/tsconfig.json similarity index 80% rename from 06 SimpleApp_Navigation/tsconfig.json rename to 05 SimpleApp_Navigation/tsconfig.json index 885d474..d279ee2 100644 --- a/06 SimpleApp_Navigation/tsconfig.json +++ b/05 SimpleApp_Navigation/tsconfig.json @@ -8,10 +8,11 @@ "jsx": "react", "sourceMap": true, "noLib": false, - "suppressImplicitAnyIndexErrors": true + "suppressImplicitAnyIndexErrors": true, + "skipLibCheck": true }, "compileOnSave": false, "exclude": [ "node_modules" ] -} +} \ No newline at end of file diff --git a/05 SimpleApp_Navigation/webpack.config.js b/05 SimpleApp_Navigation/webpack.config.js new file mode 100644 index 0000000..bd63b7f --- /dev/null +++ b/05 SimpleApp_Navigation/webpack.config.js @@ -0,0 +1,65 @@ +let path = require('path'); +let HtmlWebpackPlugin = require('html-webpack-plugin'); +let MiniCssExtractPlugin = require('mini-css-extract-plugin'); +let webpack = require('webpack'); + +let basePath = __dirname; + +module.exports = { + context: path.join(basePath, "src"), + resolve: { + extensions: ['.js', '.ts', '.tsx'] + }, + entry: [ + 'babel-polyfill', + './main.tsx', + '../node_modules/bootstrap/dist/css/bootstrap.css' + ], + output: { + path: path.join(basePath, 'dist'), + filename: 'bundle.js' + }, + devtool: 'source-map', + devServer: { + contentBase: './dist', // Content base + inline: true, // Enable watch and live reload + host: 'localhost', + port: 8080, + stats: 'errors-only' + }, + module: { + rules: [ + { + test: /\.(ts|tsx)$/, + exclude: /node_modules/, + loader: 'awesome-typescript-loader', + options: { + useBabel: true, + }, + }, + { + test: /\.css$/, + use: [MiniCssExtractPlugin.loader, "css-loader"] + }, + { + test: /\.(png|jpg|gif|svg)$/, + loader: 'file-loader', + options: { + name: 'assets/img/[name].[ext]?[hash]' + } + }, + ], + }, + plugins: [ + //Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin + new HtmlWebpackPlugin({ + filename: 'index.html', //Name of file in ./dist/ + template: 'index.html', //Name of template in ./src + hash: true, + }), + new MiniCssExtractPlugin({ + filename: "[name].css", + chunkFilename: "[id].css" + }), + ], +}; \ No newline at end of file diff --git a/06 SimpleApp_Navigation/.babelrc b/06 SimpleApp_Navigation/.babelrc deleted file mode 100644 index b207aef..0000000 --- a/06 SimpleApp_Navigation/.babelrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "presets": [ - "env" - ] -} diff --git a/06 SimpleApp_Navigation/package.json b/06 SimpleApp_Navigation/package.json deleted file mode 100644 index 4e515a8..0000000 --- a/06 SimpleApp_Navigation/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "samplereact", - "version": "1.0.0", - "description": "Sample working with React,TypeScript and Webpack", - "main": "index.js", - "scripts": { - "start": "webpack-dev-server", - "build": "webpack" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "@types/react": "^16.0.30", - "@types/react-dom": "^16.0.3", - "@types/react-redux": "^5.0.14", - "@types/react-router": "^3.0.13", - "@types/react-router-redux": "^4.0.51", - "@types/redux-thunk": "^2.1.0", - "awesome-typescript-loader": "^3.4.1", - "babel-core": "^6.26.0", - "babel-preset-env": "^1.6.1", - "css-loader": "^0.28.7", - "extract-text-webpack-plugin": "^3.0.2", - "file-loader": "^1.1.5", - "html-webpack-plugin": "^2.30.1", - "style-loader": "^0.19.1", - "ts-loader": "^3.2.0", - "typescript": "^2.6.2", - "url-loader": "^0.6.2", - "webpack": "^3.10.0", - "webpack-dev-server": "^2.9.7" - }, - "dependencies": { - "babel-polyfill": "^6.26.0", - "bootstrap": "^3.3.7", - "react": "^16.2.0", - "react-dom": "^16.2.0", - "react-redux": "^5.0.6", - "react-router": "^3.2.0", - "react-router-redux": "^4.0.8", - "redux": "^3.7.2", - "redux-thunk": "^2.2.0" - } -} diff --git a/06 SimpleApp_Navigation/src/app.tsx b/06 SimpleApp_Navigation/src/app.tsx deleted file mode 100644 index 2251ee4..0000000 --- a/06 SimpleApp_Navigation/src/app.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import * as React from 'react' -import { Link } from 'react-router' - -export const App = (props: { children? }) => { - return ( -
-
- Links: - {' '} - Login - {' '} - Student List - {' '} - Student Detail -
-
{props.children}
-
- ) -} diff --git a/06 SimpleApp_Navigation/src/model/login.ts b/06 SimpleApp_Navigation/src/model/login.ts deleted file mode 100644 index 0fbac16..0000000 --- a/06 SimpleApp_Navigation/src/model/login.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class LoginEntity { - login : string; - password : string; - - public constructor() { - this.login = ''; - this.password = ''; - } -} diff --git a/06 SimpleApp_Navigation/src/model/userProfile.ts b/06 SimpleApp_Navigation/src/model/userProfile.ts deleted file mode 100644 index 447ff4f..0000000 --- a/06 SimpleApp_Navigation/src/model/userProfile.ts +++ /dev/null @@ -1,4 +0,0 @@ -export class UserProfile { - fullname : string; - role : string; -} diff --git a/06 SimpleApp_Navigation/src/pages/login/actions/loginRequestCompleted.ts b/06 SimpleApp_Navigation/src/pages/login/actions/loginRequestCompleted.ts deleted file mode 100644 index 8ff26bd..0000000 --- a/06 SimpleApp_Navigation/src/pages/login/actions/loginRequestCompleted.ts +++ /dev/null @@ -1,9 +0,0 @@ -import {actionsEnums} from '../../../common/actionsEnums'; -import {LoginResponse} from '../../../model/loginResponse'; - -export const loginRequestCompletedAction = (loginResponse : LoginResponse) => { - return { - type: actionsEnums.USERPROFILE_PERFORM_LOGIN, - payload: loginResponse - } -} diff --git a/06 SimpleApp_Navigation/src/pages/login/actions/loginRequestStarted.ts b/06 SimpleApp_Navigation/src/pages/login/actions/loginRequestStarted.ts deleted file mode 100644 index bd67962..0000000 --- a/06 SimpleApp_Navigation/src/pages/login/actions/loginRequestStarted.ts +++ /dev/null @@ -1,25 +0,0 @@ -import {actionsEnums} from '../../../common/actionsEnums'; -import {LoginEntity} from '../../../model/login'; -import {loginApi} from '../../../rest-api/loginApi'; -import {loginRequestCompletedAction} from './loginRequestCompleted'; -import { hashHistory } from 'react-router'; - -export const loginRequestStartedAction = (login : LoginEntity) => { - return function(dispatcher) { - const promise = loginApi.login(login); - - promise.then( - data => { - dispatcher(loginRequestCompletedAction(data)); - - // This is not ideal to have it here, maybe move it to middleware? - if(data.succeeded == true) { - hashHistory.push('/student-list'); - } - } - - ); - - return promise; - } -} diff --git a/06 SimpleApp_Navigation/src/pages/login/actions/updateEditingLogin.ts b/06 SimpleApp_Navigation/src/pages/login/actions/updateEditingLogin.ts deleted file mode 100644 index 65bcc11..0000000 --- a/06 SimpleApp_Navigation/src/pages/login/actions/updateEditingLogin.ts +++ /dev/null @@ -1,9 +0,0 @@ -import {actionsEnums} from '../../../common/actionsEnums'; -import {LoginEntity} from '../../../model/login'; - -export const updateEditingLogin = (loginInfo : LoginEntity) => { - return { - type: actionsEnums.USERPROFILE_UPDATE_EDITING_LOGIN, - payload: loginInfo - } -} diff --git a/06 SimpleApp_Navigation/src/pages/login/index.ts b/06 SimpleApp_Navigation/src/pages/login/index.ts deleted file mode 100644 index 099495b..0000000 --- a/06 SimpleApp_Navigation/src/pages/login/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { LoginContainer } from './loginContainer' - -export { - LoginContainer -} \ No newline at end of file diff --git a/06 SimpleApp_Navigation/src/pages/login/login.tsx b/06 SimpleApp_Navigation/src/pages/login/login.tsx deleted file mode 100644 index 8f68885..0000000 --- a/06 SimpleApp_Navigation/src/pages/login/login.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from 'react'; -import {Header} from './components/header'; -import {Form} from './components/form'; -import {LoginEntity} from '../../model/login'; - -interface Props { - loginInfo : LoginEntity; - updateLoginInfo : (loginInfo : LoginEntity) => void; - performLogin : (loginInfo : LoginEntity) => void; -} - -export const LoginComponent = (props : Props) => { - return ( -
-
-
-
-
- props.performLogin(props.loginInfo)} - /> -
-
-
-
- ) -} diff --git a/06 SimpleApp_Navigation/src/pages/login/loginContainer.tsx b/06 SimpleApp_Navigation/src/pages/login/loginContainer.tsx deleted file mode 100644 index fe5135e..0000000 --- a/06 SimpleApp_Navigation/src/pages/login/loginContainer.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { connect } from 'react-redux'; -import { LoginComponent } from './login'; -import { LoginEntity } from '../../model/login'; -import { updateEditingLogin } from './actions/updateEditingLogin'; -import { loginRequestStartedAction} from './actions/loginRequestStarted'; - -const mapStateToProps = (state) => { - return { - loginInfo: state.sessionReducer.editingLogin - } -} - -const mapDispatchToProps = (dispatch) => { - return { - updateLoginInfo: (loginInfo : LoginEntity) => dispatch(updateEditingLogin(loginInfo)), - performLogin: (loginInfo : LoginEntity) => dispatch(loginRequestStartedAction(loginInfo)) - } -} - -export const LoginContainer = connect( - mapStateToProps - ,mapDispatchToProps - )(LoginComponent); diff --git a/06 SimpleApp_Navigation/src/pages/student-detail/index.tsx b/06 SimpleApp_Navigation/src/pages/student-detail/index.tsx deleted file mode 100644 index ba7f440..0000000 --- a/06 SimpleApp_Navigation/src/pages/student-detail/index.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import {StudentDetailContainer} from './studentDetailContainer'; - -export { - StudentDetailContainer -} diff --git a/06 SimpleApp_Navigation/src/pages/student-list/index.ts b/06 SimpleApp_Navigation/src/pages/student-list/index.ts deleted file mode 100644 index 435be76..0000000 --- a/06 SimpleApp_Navigation/src/pages/student-list/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {StudentListContainer} from './studentListContainer'; - -export { - StudentListContainer -} diff --git a/06 SimpleApp_Navigation/src/reducers/index.ts b/06 SimpleApp_Navigation/src/reducers/index.ts deleted file mode 100644 index f7dc905..0000000 --- a/06 SimpleApp_Navigation/src/reducers/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { combineReducers } from 'redux'; -import { sessionReducer } from './session'; -import { routerReducer } from 'react-router-redux' - -export const reducers = combineReducers({ - sessionReducer, - routing: routerReducer -}); diff --git a/06 SimpleApp_Navigation/src/reducers/session.ts b/06 SimpleApp_Navigation/src/reducers/session.ts deleted file mode 100644 index dbd2b9c..0000000 --- a/06 SimpleApp_Navigation/src/reducers/session.ts +++ /dev/null @@ -1,48 +0,0 @@ -import {actionsEnums} from '../common/actionsEnums'; -import {UserProfile} from '../model/userProfile'; -import {LoginResponse} from '../model/loginResponse'; -import {LoginEntity} from '../model/login'; - -class SessionState { - isUserLoggedIn : boolean; - userProfile : UserProfile; - editingLogin : LoginEntity; - - public constructor() - { - this.isUserLoggedIn = false; - this.userProfile = new UserProfile(); - this.editingLogin = new LoginEntity(); - } -} - -export const sessionReducer = (state : SessionState = new SessionState(), action) => { - switch (action.type) { - case actionsEnums.USERPROFILE_PERFORM_LOGIN: - return handlePerformLogin(state, action.payload); - case actionsEnums.USERPROFILE_UPDATE_EDITING_LOGIN: - return handleUpdateEditingLogin(state, action.payload); - - } - - return state; -}; - - -const handlePerformLogin = (state : SessionState, payload : LoginResponse) => { - return {...state, - isUserLoggedIn: payload.succeeded, - userProfile: payload.userProfile - }; -} - - -const handleUpdateEditingLogin = (state: SessionState, payload : LoginEntity) => { - const newState = { - ...state, - editingLogin: payload - }; - - return newState; -} - diff --git a/06 SimpleApp_Navigation/webpack.config.js b/06 SimpleApp_Navigation/webpack.config.js deleted file mode 100644 index acbd811..0000000 --- a/06 SimpleApp_Navigation/webpack.config.js +++ /dev/null @@ -1,89 +0,0 @@ -var path = require('path'); -var webpack = require('webpack'); -var HtmlWebpackPlugin = require('html-webpack-plugin'); -var ExtractTextPlugin = require('extract-text-webpack-plugin'); - -var basePath = __dirname; - -module.exports = { - context: path.join(basePath, "src"), - resolve: { - extensions: ['.js', '.ts', '.tsx'] - }, - - entry: [ - 'babel-polyfill', - './main.tsx', - '../node_modules/bootstrap/dist/css/bootstrap.css' - ], - output: { - path: path.join(basePath, 'dist'), - filename: 'bundle.js' - }, - - devtool: 'source-map', - - devServer: { - contentBase: './dist', // Content base - inline: true, // Enable watch and live reload - host: 'localhost', - port: 8080, - stats: 'errors-only' - }, - - module: { - rules: [ - { - test: /\.(ts|tsx)$/, - exclude: /node_modules/, - use: { - loader: 'awesome-typescript-loader', - options: { - useBabel: true, - }, - }, - }, - { - test: /\.css$/, - include: /node_modules/, - loader: ExtractTextPlugin.extract({ - fallback: 'style-loader', - use: { - loader: 'css-loader', - }, - }), - }, - // Loading glyphicons => https://github.com/gowravshekar/bootstrap-webpack - // Using here url-loader and file-loader - { - test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/, - loader: 'url-loader?limit=10000&mimetype=application/font-woff' - }, - { - test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, - loader: 'url-loader?limit=10000&mimetype=application/octet-stream' - }, - { - test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, - loader: 'url-loader?limit=10000&mimetype=image/svg+xml' - }, - { - test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, - loader: 'file-loader' - }, - ] - }, - plugins: [ - // Generate index.html in /dist => https://github.com/ampedandwired/html-webpack-plugin - new HtmlWebpackPlugin({ - filename: 'index.html', // Name of file in ./dist/ - template: 'index.html', // Name of template in ./src - hash: true - }), - new ExtractTextPlugin({ - filename: '[chunkhash].[name].css', - disable: false, - allChunks: true, - }), - ] -}