ing
This commit is contained in:
parent
77b2c1ed7b
commit
9139cd82ae
27
package.json
27
package.json
|
@ -20,15 +20,18 @@
|
||||||
"stats": "set NODE_ENV=production && webpack --progress --config ./config/webpack/webpack.config.stats.js --profile --json > ./config/webpack/stats/stats.json"
|
"stats": "set NODE_ENV=production && webpack --progress --config ./config/webpack/webpack.config.stats.js --profile --json > ./config/webpack/stats/stats.json"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/auth0-lock": "^10.16.0",
|
||||||
|
"@types/history": "^4.6.0",
|
||||||
"@types/jest": "^19.2.4",
|
"@types/jest": "^19.2.4",
|
||||||
"@types/material-ui": "^0.17.11",
|
"@types/material-ui": "^0.17.11",
|
||||||
"@types/prop-types": "^15.5.1",
|
"@types/prop-types": "^15.5.1",
|
||||||
"@types/react": "^15.0.24",
|
"@types/react": "^15.0.32",
|
||||||
"@types/react-addons-test-utils": "^0.14.18",
|
"@types/react-addons-test-utils": "^0.14.19",
|
||||||
"@types/react-dom": "^15.5.0",
|
"@types/react-dom": "^15.5.1",
|
||||||
"@types/react-redux": "4.4.40",
|
"@types/react-redux": "^4.4.45",
|
||||||
"@types/react-router": "^4.0.9",
|
"@types/react-router": "^4.0.12",
|
||||||
"@types/react-router-dom": "^4.0.4",
|
"@types/react-router-dom": "^4.0.5",
|
||||||
|
"@types/react-router-redux": "^5.0.3",
|
||||||
"@types/react-tap-event-plugin": "^0.0.30",
|
"@types/react-tap-event-plugin": "^0.0.30",
|
||||||
"@types/redux": "^3.6.0",
|
"@types/redux": "^3.6.0",
|
||||||
"@types/redux-actions": "^1.2.6",
|
"@types/redux-actions": "^1.2.6",
|
||||||
|
@ -62,22 +65,24 @@
|
||||||
"webpack-visualizer-plugin": "^0.1.11"
|
"webpack-visualizer-plugin": "^0.1.11"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"auth0-lock": "^10.18.0",
|
||||||
|
"history": "^4.6.3",
|
||||||
"immutable": "^3.8.1",
|
"immutable": "^3.8.1",
|
||||||
"material-ui": "^0.18.3",
|
"material-ui": "^0.18.3",
|
||||||
"prop-types": "^15.5.10",
|
"prop-types": "^15.5.10",
|
||||||
"react": "^15.5.4",
|
"react": "^15.6.1",
|
||||||
"react-dom": "15.5.4",
|
"react-dom": "^15.6.1",
|
||||||
"react-immutable-proptypes": "^2.1.0",
|
"react-immutable-proptypes": "^2.1.0",
|
||||||
"react-redux": "^5.0.5",
|
"react-redux": "^5.0.5",
|
||||||
"react-router": "^4.1.1",
|
"react-router": "^4.1.1",
|
||||||
"react-router-dom": "^4.1.1",
|
"react-router-dom": "^4.1.1",
|
||||||
|
"react-router-redux": "next",
|
||||||
"react-tap-event-plugin": "^2.0.1",
|
"react-tap-event-plugin": "^2.0.1",
|
||||||
"redux": "^3.6.0",
|
"redux": "^3.7.1",
|
||||||
"redux-actions": "^2.0.3",
|
"redux-actions": "^2.0.3",
|
||||||
"redux-saga": "^0.15.3",
|
"redux-saga": "^0.15.4",
|
||||||
"reselect": "^3.0.1"
|
"reselect": "^3.0.1"
|
||||||
},
|
},
|
||||||
|
|
||||||
"jest": {
|
"jest": {
|
||||||
"moduleFileExtensions": [
|
"moduleFileExtensions": [
|
||||||
"ts",
|
"ts",
|
||||||
|
|
31
src/ts/app/views/container/component/App.tsx
Normal file
31
src/ts/app/views/container/component/App.tsx
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import * as ReactDOM from 'react-dom';
|
||||||
|
import { Route } from 'react-router-dom';
|
||||||
|
import { RouteComponentProps, Switch } from 'react-router';
|
||||||
|
|
||||||
|
import Signin from 'member/signin/views/Signin';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class App extends React.Component<Props, State> {
|
||||||
|
public constructor(props: Props, context: State) {
|
||||||
|
super(props, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): JSX.Element {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Switch>
|
||||||
|
<Route exact path='/' component={Signin} />
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
8
src/ts/commons/module/Module.ts
Normal file
8
src/ts/commons/module/Module.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
interface IModule<IComponentType, IContainerType, IViewType, IReduxType> {
|
||||||
|
components: IComponentType;
|
||||||
|
containers: IContainerType;
|
||||||
|
views: IViewType;
|
||||||
|
redux: IReduxType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default IModule;
|
|
@ -1,8 +1,8 @@
|
||||||
interface Action<Payload = {}> {
|
import * as Redux from 'redux';
|
||||||
type: any;
|
|
||||||
|
interface Action<Payload = {}> extends Redux.Action {
|
||||||
payload?: Payload;
|
payload?: Payload;
|
||||||
error?: Error;
|
error?: Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default Action;
|
export default Action;
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
import Action from './Action';
|
import Action from './Action';
|
||||||
|
|
||||||
interface IModule<State, Payload> {
|
export interface IModule<State = {}, Payload = {}> {
|
||||||
Name: string;
|
state: State;
|
||||||
ActionTypes: {[key: string]: any};
|
reducer: (state: State, action: Action<Payload>) => State;
|
||||||
Actions: {[key: string]: any};
|
|
||||||
Reducer: (state: State, action: Action<Payload>) => State;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default IModule;
|
export default IModule;
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
import { Iterable, Map, Record as ImmutableRecord } from 'immutable';
|
|
||||||
|
|
||||||
export interface Record<T extends Record<T>> extends Map<string, any> {
|
|
||||||
set: (prop: string, val: any) => T;
|
|
||||||
delete: (key: string) => T;
|
|
||||||
remove: (key: string) => T;
|
|
||||||
clear: () => T;
|
|
||||||
update: {
|
|
||||||
(updater: (value: T) => any): T;
|
|
||||||
(key: string, updater: (value: any) => any): T;
|
|
||||||
(key: string, notSetValue: any, updater: (value: any) => any): T;
|
|
||||||
};
|
|
||||||
merge: (obj: any) => T;
|
|
||||||
mergeWith: (
|
|
||||||
merger: (previous?: any, next?: any, key?: string) => any,
|
|
||||||
obj: any,
|
|
||||||
) => T;
|
|
||||||
mergeDeep: (obj: any) => T;
|
|
||||||
mergeDeepWith: (
|
|
||||||
merger: (previous?: any, next?: any, key?: string) => any,
|
|
||||||
obj: any,
|
|
||||||
) => T;
|
|
||||||
setIn: (keyPath: any[] | Iterable<any, any>, value: any) => T;
|
|
||||||
deleteIn: (keyPath: Array<any> | Iterable<any, any>) => T;
|
|
||||||
removeIn: (keyPath: Array<any> | Iterable<any, any>) => T;
|
|
||||||
updateIn: {
|
|
||||||
(keyPath: any[] | Iterable<any, any>, updater: (value: any) => any): T;
|
|
||||||
(
|
|
||||||
keyPath: any[] | Iterable<any, any>,
|
|
||||||
notSetValue: any,
|
|
||||||
updater: (value: any) => any,
|
|
||||||
): T
|
|
||||||
};
|
|
||||||
mergeIn: (keyPath: any[] | Iterable<any, any>, obj: any) => T;
|
|
||||||
mergeDeepIn: (keyPath: any[] | Iterable<any, any>, obj: any) => T;
|
|
||||||
withMutations: (mutator: (mutable: T) => any) => T;
|
|
||||||
asMutable: () => T;
|
|
||||||
asImmutable: () => T;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function makeRecordType<O, R extends Record<R> & O>
|
|
||||||
(defaultVal: O, val: O = null, name?: string): R {
|
|
||||||
|
|
||||||
const RecordFactory = makeRecordFactory<O, R>(defaultVal, name);
|
|
||||||
return val ? RecordFactory(val) : RecordFactory();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function makeRecordFactory<O, R extends Record<R> & O>
|
|
||||||
(obj: O, name?: string): (val?: O) => R {
|
|
||||||
|
|
||||||
const iRecord = ImmutableRecord(obj, name);
|
|
||||||
return (val: O = null) => {
|
|
||||||
return new iRecord(val) as R;
|
|
||||||
};
|
|
||||||
}
|
|
9
src/ts/commons/util/system/index.ts
Normal file
9
src/ts/commons/util/system/index.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
export function* getAppContainer(containerId: string): any {
|
||||||
|
const appContainer = yield new Promise(resolve => {
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
resolve(document.getElementById(containerId));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return appContainer;
|
||||||
|
}
|
25
src/ts/config/configureMuiTheme.ts
Normal file
25
src/ts/config/configureMuiTheme.ts
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import { colors, getMuiTheme, MuiTheme, spacing } from 'material-ui/styles';
|
||||||
|
import { fade } from 'material-ui/utils/colorManipulator';
|
||||||
|
|
||||||
|
const muiTheme:MuiTheme = getMuiTheme({
|
||||||
|
spacing: spacing,
|
||||||
|
fontFamily: 'Roboto, sans-serif',
|
||||||
|
palette: {
|
||||||
|
primary1Color: colors.cyan500,
|
||||||
|
primary2Color: colors.cyan700,
|
||||||
|
primary3Color: colors.grey400,
|
||||||
|
accent1Color: colors.pinkA200,
|
||||||
|
accent2Color: colors.grey100,
|
||||||
|
accent3Color: colors.grey500,
|
||||||
|
textColor: colors.darkBlack,
|
||||||
|
alternateTextColor: colors.white,
|
||||||
|
canvasColor: colors.white,
|
||||||
|
borderColor: colors.grey300,
|
||||||
|
disabledColor: fade(colors.darkBlack, 0.3),
|
||||||
|
pickerHeaderColor: colors.cyan500,
|
||||||
|
clockCircleColor: fade(colors.darkBlack, 0.07),
|
||||||
|
shadowColor: colors.fullBlack,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default muiTheme;
|
14
src/ts/config/configureRedux.ts
Normal file
14
src/ts/config/configureRedux.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import { Action, combineReducers } from 'redux';
|
||||||
|
import { routerReducer, RouterState } from 'react-router-redux';
|
||||||
|
|
||||||
|
import * as Member from 'member';
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
member: Member.State;
|
||||||
|
router: RouterState;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const reducer = combineReducers<State>({
|
||||||
|
member: Member.reducer,
|
||||||
|
router: routerReducer,
|
||||||
|
});
|
2
src/ts/config/configureRouter.tsx
Normal file
2
src/ts/config/configureRouter.tsx
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
|
18
src/ts/config/configureStore.ts
Normal file
18
src/ts/config/configureStore.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { applyMiddleware, compose, createStore, Store } from 'redux';
|
||||||
|
import { routerMiddleware } from 'react-router-redux';
|
||||||
|
import { SagaMiddleware } from 'redux-saga';
|
||||||
|
import { History } from 'history';
|
||||||
|
|
||||||
|
import { reducer, State } from './configureRedux';
|
||||||
|
|
||||||
|
export default function configureStore(history: History, sagaMiddleware: SagaMiddleware<any>): Store<State> {
|
||||||
|
const middlewares = [sagaMiddleware, routerMiddleware(history)];
|
||||||
|
const store = createStore<State>(
|
||||||
|
reducer,
|
||||||
|
applyMiddleware(...middlewares),
|
||||||
|
);
|
||||||
|
|
||||||
|
// sagaMiddleware.run(rootSaga);
|
||||||
|
|
||||||
|
return store;
|
||||||
|
}
|
|
@ -1,32 +1,56 @@
|
||||||
import * as member from 'member/redux';
|
import * as React from 'react';
|
||||||
import { Action, createStore, combineReducers } from 'redux';
|
import * as ReactDOM from 'react-dom';
|
||||||
|
import createSagaMiddleware, { SagaMiddleware } from 'redux-saga';
|
||||||
|
import { createHashHistory } from 'history';
|
||||||
|
|
||||||
|
|
||||||
export interface StateRecord {
|
import { Provider } from 'react-redux';
|
||||||
member: member.StateRecord;
|
import { ConnectedRouter } from 'react-router-redux';
|
||||||
|
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
|
||||||
|
import * as injectTapEventPlugin from 'react-tap-event-plugin';
|
||||||
|
|
||||||
|
import * as system from 'commons/util/system';
|
||||||
|
|
||||||
|
import configureStore from 'config/configureStore';
|
||||||
|
import muiTheme from 'config/configureMuiTheme';
|
||||||
|
|
||||||
|
import App from 'app/views/container/component/App';
|
||||||
|
|
||||||
|
injectTapEventPlugin();
|
||||||
|
|
||||||
|
const sagaMiddleware: SagaMiddleware<any> = createSagaMiddleware();
|
||||||
|
|
||||||
|
const history = createHashHistory();
|
||||||
|
const store = configureStore(history, sagaMiddleware);
|
||||||
|
|
||||||
|
function* app(): any {
|
||||||
|
const appContainer = yield system.getAppContainer('react-placeholder');
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<div style={{
|
||||||
|
width: '100vw',
|
||||||
|
height: '100vh',
|
||||||
|
backgroundColor: 'white',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}>
|
||||||
|
<h1>Loading...</h1>
|
||||||
|
</div>,
|
||||||
|
appContainer,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Provider store={store}>
|
||||||
|
<ConnectedRouter history={history}>
|
||||||
|
<MuiThemeProvider muiTheme={muiTheme}>
|
||||||
|
<App/>
|
||||||
|
</MuiThemeProvider>
|
||||||
|
</ConnectedRouter>
|
||||||
|
</Provider>,
|
||||||
|
appContainer,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IActionTypes {
|
sagaMiddleware.run(app);
|
||||||
member: member.IActionTypes;
|
|
||||||
}
|
|
||||||
export const ActionTypes: IActionTypes = {
|
|
||||||
member: member.ActionTypes,
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface IActions {
|
|
||||||
member: member.IActions;
|
|
||||||
}
|
|
||||||
export const Actions: IActions = {
|
|
||||||
member: member.Actions,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const Reducers = combineReducers<StateRecord>({
|
|
||||||
member: member.Reducers,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
let store = createStore(Reducers);
|
|
||||||
|
|
||||||
console.log('');
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import {MemberStatus} from './MemberStatus';
|
import {MemberStatus} from './MemberStatus';
|
||||||
|
|
||||||
|
|
||||||
export interface Member {
|
interface Member {
|
||||||
id?: number;
|
id?: number;
|
||||||
email: string;
|
email: string;
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -10,3 +10,5 @@ export interface Member {
|
||||||
createDate?: Date;
|
createDate?: Date;
|
||||||
status?: MemberStatus;
|
status?: MemberStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default Member;
|
||||||
|
|
18
src/ts/member/index.ts
Normal file
18
src/ts/member/index.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { Action, combineReducers } from 'redux';
|
||||||
|
import IModule from 'commons/redux/Module';
|
||||||
|
|
||||||
|
import * as signin from './signin';
|
||||||
|
import * as signout from './signout';
|
||||||
|
import * as signup from './signup';
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
signin: signin.State;
|
||||||
|
signout: signin.State;
|
||||||
|
signup: signin.State;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const reducer = combineReducers<State>({
|
||||||
|
signin: signin.reducer,
|
||||||
|
signout: signout.reducer,
|
||||||
|
signup: signup.reducer,
|
||||||
|
});
|
|
@ -1,44 +0,0 @@
|
||||||
import { Action, combineReducers } from 'redux';
|
|
||||||
|
|
||||||
import * as signin from './signin';
|
|
||||||
import * as signout from './signout';
|
|
||||||
import * as signup from './signup';
|
|
||||||
|
|
||||||
export const ModuleName = 'member';
|
|
||||||
|
|
||||||
export interface StateRecord {
|
|
||||||
signin: signin.StateRecord;
|
|
||||||
signout: signout.StateRecord;
|
|
||||||
signup: signup.StateRecord;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IActionTypes {
|
|
||||||
signin: signin.IActionTypes;
|
|
||||||
signout: signout.IActionTypes;
|
|
||||||
signup: signup.IActionTypes;
|
|
||||||
}
|
|
||||||
export const ActionTypes: IActionTypes = {
|
|
||||||
signin: signin.ActionTypes,
|
|
||||||
signout: signout.ActionTypes,
|
|
||||||
signup: signup.ActionTypes,
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface IActions {
|
|
||||||
signin: signin.IActions;
|
|
||||||
signout: signout.IActions;
|
|
||||||
signup: signup.IActions;
|
|
||||||
}
|
|
||||||
export const Actions: IActions = {
|
|
||||||
signin: signin.Actions,
|
|
||||||
signout: signout.Actions,
|
|
||||||
signup: signup.Actions,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const Reducers = combineReducers<StateRecord>({
|
|
||||||
signin: signin.Reducers,
|
|
||||||
signout: signout.Reducers,
|
|
||||||
signup: signup.Reducers,
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
import Action from 'commons/redux/Action';
|
|
||||||
import { Record, makeRecordFactory } from 'commons/util/immutable/Record';
|
|
||||||
|
|
||||||
import { Member } from 'member/api/model/Member';
|
|
||||||
|
|
||||||
export const ModuleName = 'signin';
|
|
||||||
|
|
||||||
export type REQUEST = '@overflow/member/signin/REQUEST';
|
|
||||||
export type REQUEST_SUCCESS = '@overflow/member/signin/REQUEST_SUCCESS';
|
|
||||||
export type REQUEST_FAILURE = '@overflow/member/signin/REQUEST_FAILURE';
|
|
||||||
|
|
||||||
export interface SigninPayload {
|
|
||||||
signinId: string;
|
|
||||||
signinPw: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MemberPayload extends Member {
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface State {
|
|
||||||
isAuthenticated: boolean;
|
|
||||||
member?: Member;
|
|
||||||
error?: Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StateRecord extends Record<StateRecord>, State {
|
|
||||||
}
|
|
||||||
|
|
||||||
const makeStateRecord = makeRecordFactory<State, StateRecord>({
|
|
||||||
isAuthenticated: undefined,
|
|
||||||
member: undefined,
|
|
||||||
error: undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
export interface IActionTypes {
|
|
||||||
REQUEST: REQUEST;
|
|
||||||
REQUEST_SUCCESS: REQUEST_SUCCESS;
|
|
||||||
REQUEST_FAILURE: REQUEST_FAILURE;
|
|
||||||
}
|
|
||||||
export const ActionTypes: IActionTypes = {
|
|
||||||
REQUEST: '@overflow/member/signin/REQUEST',
|
|
||||||
REQUEST_SUCCESS: '@overflow/member/signin/REQUEST_SUCCESS',
|
|
||||||
REQUEST_FAILURE: '@overflow/member/signin/REQUEST_FAILURE',
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface IActions {
|
|
||||||
request: (signinId: string, signinPw: string) => Action<SigninPayload>;
|
|
||||||
requestSuccess: (member: Member) => Action<Member>;
|
|
||||||
requestFailure: (error: Error) => Action;
|
|
||||||
}
|
|
||||||
export const Actions: IActions = {
|
|
||||||
request(signinId: string, signinPw: string): Action<SigninPayload> {
|
|
||||||
return {
|
|
||||||
type: ActionTypes.REQUEST,
|
|
||||||
payload: {
|
|
||||||
signinId: signinId,
|
|
||||||
signinPw: signinPw,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
requestSuccess(member: Member): Action<Member> {
|
|
||||||
return {
|
|
||||||
type: ActionTypes.REQUEST,
|
|
||||||
payload: member,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
requestFailure(error: Error): Action {
|
|
||||||
return {
|
|
||||||
type: ActionTypes.REQUEST,
|
|
||||||
error: error,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export function Reducers(state: StateRecord = makeStateRecord(), action: Action<MemberPayload | Error>): StateRecord {
|
|
||||||
switch (action.type) {
|
|
||||||
case ActionTypes.REQUEST_SUCCESS:
|
|
||||||
{
|
|
||||||
return state.merge({isAuthenticated: true, member: action.payload});
|
|
||||||
}
|
|
||||||
case ActionTypes.REQUEST_FAILURE:
|
|
||||||
{
|
|
||||||
return state.merge({isAuthenticated: false, error: action.error});
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
import Action from 'commons/redux/Action';
|
|
||||||
import { Record, makeRecordFactory } from 'commons/util/immutable/Record';
|
|
||||||
import { Member } from 'member/api/model/Member';
|
|
||||||
export type REQUEST = '@overflow/member/signout/REQUEST';
|
|
||||||
export type REQUEST_SUCCESS = '@overflow/member/signout/REQUEST_SUCCESS';
|
|
||||||
export type REQUEST_FAILURE = '@overflow/member/signout/REQUEST_FAILURE';
|
|
||||||
|
|
||||||
export const ModuleName = 'signout';
|
|
||||||
|
|
||||||
export interface State {
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StateRecord extends Record<StateRecord>, State {
|
|
||||||
}
|
|
||||||
|
|
||||||
const makeStateRecord = makeRecordFactory<State, StateRecord>({
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
export interface IActionTypes {
|
|
||||||
REQUEST: REQUEST;
|
|
||||||
REQUEST_SUCCESS: REQUEST_SUCCESS;
|
|
||||||
REQUEST_FAILURE: REQUEST_FAILURE;
|
|
||||||
}
|
|
||||||
export const ActionTypes: IActionTypes = {
|
|
||||||
REQUEST: '@overflow/member/signout/REQUEST',
|
|
||||||
REQUEST_SUCCESS: '@overflow/member/signout/REQUEST_SUCCESS',
|
|
||||||
REQUEST_FAILURE: '@overflow/member/signout/REQUEST_FAILURE',
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface IActions {
|
|
||||||
request: () => Action;
|
|
||||||
requestSuccess: () => Action;
|
|
||||||
requestFailure: (error: Error) => Action;
|
|
||||||
}
|
|
||||||
export const Actions: IActions = {
|
|
||||||
request(): Action {
|
|
||||||
return {
|
|
||||||
type: ActionTypes.REQUEST,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
requestSuccess(): Action {
|
|
||||||
return {
|
|
||||||
type: ActionTypes.REQUEST,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
requestFailure(error: Error): Action {
|
|
||||||
return {
|
|
||||||
type: ActionTypes.REQUEST,
|
|
||||||
error: error,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export function Reducers(state: StateRecord = makeStateRecord(), action: Action): StateRecord {
|
|
||||||
switch (action.type) {
|
|
||||||
case ActionTypes.REQUEST_SUCCESS:
|
|
||||||
{
|
|
||||||
return state.merge({isAuthenticated: true, member: action.payload});
|
|
||||||
}
|
|
||||||
case ActionTypes.REQUEST_FAILURE:
|
|
||||||
{
|
|
||||||
return state.merge({isAuthenticated: false, error: action.error});
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
import Action from 'commons/redux/Action';
|
|
||||||
import { Record, makeRecordFactory } from 'commons/util/immutable/Record';
|
|
||||||
import { Member } from 'member/api/model/Member';
|
|
||||||
|
|
||||||
export const ModuleName = 'signup';
|
|
||||||
|
|
||||||
export type REQUEST = '@overflow/member/signup/REQUEST';
|
|
||||||
export type REQUEST_SUCCESS = '@overflow/member/signup/REQUEST_SUCCESS';
|
|
||||||
export type REQUEST_FAILURE = '@overflow/member/signup/REQUEST_FAILURE';
|
|
||||||
|
|
||||||
export interface MemberPayload extends Member {
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface State {
|
|
||||||
isRegistered: boolean;
|
|
||||||
member?: Member;
|
|
||||||
error?: Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StateRecord extends Record<StateRecord>, State {
|
|
||||||
}
|
|
||||||
|
|
||||||
const makeStateRecord = makeRecordFactory<State, StateRecord>({
|
|
||||||
isRegistered: undefined,
|
|
||||||
member: undefined,
|
|
||||||
error: undefined,
|
|
||||||
});
|
|
||||||
|
|
||||||
export interface IActionTypes {
|
|
||||||
REQUEST: REQUEST;
|
|
||||||
REQUEST_SUCCESS: REQUEST_SUCCESS;
|
|
||||||
REQUEST_FAILURE: REQUEST_FAILURE;
|
|
||||||
}
|
|
||||||
export const ActionTypes: IActionTypes = {
|
|
||||||
REQUEST: '@overflow/member/signup/REQUEST',
|
|
||||||
REQUEST_SUCCESS: '@overflow/member/signup/REQUEST_SUCCESS',
|
|
||||||
REQUEST_FAILURE: '@overflow/member/signup/REQUEST_FAILURE',
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface IActions {
|
|
||||||
request: (member: Member) => Action<MemberPayload>;
|
|
||||||
requestSuccess: (member: Member) => Action<Member>;
|
|
||||||
requestFailure: (error: Error) => Action;
|
|
||||||
}
|
|
||||||
export const Actions: IActions = {
|
|
||||||
request(member: Member): Action<MemberPayload> {
|
|
||||||
return {
|
|
||||||
type: ActionTypes.REQUEST,
|
|
||||||
payload: member,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
requestSuccess(member: Member): Action<Member> {
|
|
||||||
return {
|
|
||||||
type: ActionTypes.REQUEST,
|
|
||||||
payload: member,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
requestFailure(error: Error): Action {
|
|
||||||
return {
|
|
||||||
type: ActionTypes.REQUEST,
|
|
||||||
error: error,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export function Reducers(state: StateRecord = makeStateRecord(), action: Action<MemberPayload | Error>): StateRecord {
|
|
||||||
switch (action.type) {
|
|
||||||
case ActionTypes.REQUEST_SUCCESS:
|
|
||||||
{
|
|
||||||
return state.merge({isRegistered: true, member: action.payload});
|
|
||||||
}
|
|
||||||
case ActionTypes.REQUEST_FAILURE:
|
|
||||||
{
|
|
||||||
return state.merge({isRegistered: false, error: action.error});
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
}
|
|
1
src/ts/member/signin/index.ts
Normal file
1
src/ts/member/signin/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from './redux';
|
41
src/ts/member/signin/redux/action/index.ts
Normal file
41
src/ts/member/signin/redux/action/index.ts
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import Action from 'commons/redux/Action';
|
||||||
|
|
||||||
|
import Member from 'member/api/model/Member';
|
||||||
|
|
||||||
|
import actionTypes from './type';
|
||||||
|
import SigninPayload from '../payload/SigninPayload';
|
||||||
|
|
||||||
|
|
||||||
|
export interface Actions {
|
||||||
|
request: (signinId: string, signinPw: string) => Action<SigninPayload>;
|
||||||
|
requestSuccess: (member: Member) => Action<Member>;
|
||||||
|
requestFailure: (error: Error) => Action;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const actions: Actions = {
|
||||||
|
request(signinId: string, signinPw: string): Action<SigninPayload> {
|
||||||
|
return {
|
||||||
|
type: actionTypes.REQUEST,
|
||||||
|
payload: {
|
||||||
|
signinId: signinId,
|
||||||
|
signinPw: signinPw,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
requestSuccess(member: Member): Action<Member> {
|
||||||
|
return {
|
||||||
|
type: actionTypes.REQUEST,
|
||||||
|
payload: member,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
requestFailure(error: Error): Action {
|
||||||
|
return {
|
||||||
|
type: actionTypes.REQUEST,
|
||||||
|
error: error,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default actions;
|
17
src/ts/member/signin/redux/action/type.ts
Normal file
17
src/ts/member/signin/redux/action/type.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
export type REQUEST = '@overflow/member/signin/REQUEST';
|
||||||
|
export type REQUEST_SUCCESS = '@overflow/member/signin/REQUEST_SUCCESS';
|
||||||
|
export type REQUEST_FAILURE = '@overflow/member/signin/REQUEST_FAILURE';
|
||||||
|
|
||||||
|
export interface ActionTypes {
|
||||||
|
REQUEST: REQUEST;
|
||||||
|
REQUEST_SUCCESS: REQUEST_SUCCESS;
|
||||||
|
REQUEST_FAILURE: REQUEST_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const actionTypes: ActionTypes = {
|
||||||
|
REQUEST: '@overflow/member/signin/REQUEST',
|
||||||
|
REQUEST_SUCCESS: '@overflow/member/signin/REQUEST_SUCCESS',
|
||||||
|
REQUEST_FAILURE: '@overflow/member/signin/REQUEST_FAILURE',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default actionTypes;
|
2
src/ts/member/signin/redux/index.ts
Normal file
2
src/ts/member/signin/redux/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './state';
|
||||||
|
export * from './reducer';
|
6
src/ts/member/signin/redux/payload/SigninPayload.ts
Normal file
6
src/ts/member/signin/redux/payload/SigninPayload.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
interface SigninPayload {
|
||||||
|
signinId: string;
|
||||||
|
signinPw: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SigninPayload;
|
24
src/ts/member/signin/redux/reducer/index.ts
Normal file
24
src/ts/member/signin/redux/reducer/index.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import Action from 'commons/redux/Action';
|
||||||
|
import IModule from 'commons/redux/Module';
|
||||||
|
|
||||||
|
import Member from 'member/api/model/Member';
|
||||||
|
|
||||||
|
import actionTypes from '../action/type';
|
||||||
|
import State, { defaultState } from '../state';
|
||||||
|
|
||||||
|
|
||||||
|
export function reducer(state: State = defaultState, action: Action<Member | Error>): State {
|
||||||
|
switch (action.type) {
|
||||||
|
case actionTypes.REQUEST_SUCCESS:
|
||||||
|
{
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
case actionTypes.REQUEST_FAILURE:
|
||||||
|
{
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
43
src/ts/member/signin/redux/saga/index.ts
Normal file
43
src/ts/member/signin/redux/saga/index.ts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import { takeLatest, SagaIterator } from 'redux-saga';
|
||||||
|
import { call, put } from 'redux-saga/effects';
|
||||||
|
|
||||||
|
import Action from 'commons/redux/Action';
|
||||||
|
|
||||||
|
import Member from 'member/api/model/Member';
|
||||||
|
import actions from '../action';
|
||||||
|
import actionTypes from '../action/type';
|
||||||
|
import SigninPayload from '../payload/SigninPayload';
|
||||||
|
|
||||||
|
export function* signin(action: Action<SigninPayload>): SagaIterator {
|
||||||
|
try {
|
||||||
|
const {signinId, signinPw} = action.payload;
|
||||||
|
// yield put({
|
||||||
|
// type: types.SENDING_REQUEST,
|
||||||
|
// payload: {sendingRequest: true},
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const responseBody = yield call(api.login, signinId, signinPw);
|
||||||
|
|
||||||
|
// if (responseBody.token === undefined) {
|
||||||
|
// throw new Error(MESSAGES.UNABLE_TO_FIND_TOKEN_IN_LOGIN_RESPONSE);
|
||||||
|
// }
|
||||||
|
let member: Member = {
|
||||||
|
email: 'crusader@loafle.com',
|
||||||
|
name: 'crusader',
|
||||||
|
phone: '02-900-9000',
|
||||||
|
companyName: 'LOAFLE',
|
||||||
|
};
|
||||||
|
yield put(actions.requestSuccess(member));
|
||||||
|
} catch (e) {
|
||||||
|
yield put(actions.requestFailure(e));
|
||||||
|
} finally {
|
||||||
|
// yield put({
|
||||||
|
// type: types.SENDING_REQUEST,
|
||||||
|
// payload: {sendingRequest: false},
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function* watchSignin(): any {
|
||||||
|
yield takeLatest(actionTypes.REQUEST, signin);
|
||||||
|
}
|
15
src/ts/member/signin/redux/state/index.ts
Normal file
15
src/ts/member/signin/redux/state/index.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import Member from 'member/api/model/Member';
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
isAuthenticated: boolean;
|
||||||
|
member?: Member;
|
||||||
|
error?: Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultState: State = {
|
||||||
|
isAuthenticated: undefined,
|
||||||
|
member: undefined,
|
||||||
|
error: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default State;
|
14
src/ts/member/signin/views/Signin.tsx
Normal file
14
src/ts/member/signin/views/Signin.tsx
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import { RouteComponentProps } from 'react-router';
|
||||||
|
import SigninContainer from './containers/Signin';
|
||||||
|
|
||||||
|
class Signin extends React.Component<RouteComponentProps<object>, object> {
|
||||||
|
public render(): JSX.Element {
|
||||||
|
return (
|
||||||
|
<SigninContainer/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default Signin;
|
30
src/ts/member/signin/views/containers/Signin.tsx
Normal file
30
src/ts/member/signin/views/containers/Signin.tsx
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
import { connect, Dispatch } from 'react-redux';
|
||||||
|
import {
|
||||||
|
Signin,
|
||||||
|
Props as SigninProps,
|
||||||
|
State as SigninState,
|
||||||
|
} from './components/Signin';
|
||||||
|
|
||||||
|
import signinActions from 'member/signin/redux/action';
|
||||||
|
|
||||||
|
|
||||||
|
export function mapStateToProps(state: any): SigninProps {
|
||||||
|
return {
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapDispatchToProps(dispatch: Dispatch<any>): SigninProps {
|
||||||
|
return {
|
||||||
|
onSignin: (signinId: string, signinPw: string) => {
|
||||||
|
dispatch(signinActions.request(signinId, signinPw));
|
||||||
|
},
|
||||||
|
onSignup: () => {
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
onResetPassword: () => {
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(Signin);
|
90
src/ts/member/signin/views/containers/components/Signin.tsx
Normal file
90
src/ts/member/signin/views/containers/components/Signin.tsx
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import * as ReactDOM from 'react-dom';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
Divider,
|
||||||
|
FlatButton,
|
||||||
|
MenuItem,
|
||||||
|
Paper,
|
||||||
|
RaisedButton,
|
||||||
|
SelectField,
|
||||||
|
Slider,
|
||||||
|
TextField,
|
||||||
|
} from 'material-ui';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
onSignin?: (signinId: string, signinPw: string) => void;
|
||||||
|
onSignup?: () => void;
|
||||||
|
onResetPassword?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
signinId: string;
|
||||||
|
signinPw: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Signin extends React.Component<Props, State> {
|
||||||
|
public static defaultProps: Partial<Props> = {
|
||||||
|
onSignin: (signinId: string, signinPw: string): void => {
|
||||||
|
console.log('onSignin');
|
||||||
|
},
|
||||||
|
onSignup: (): void => {
|
||||||
|
console.log('onSignup');
|
||||||
|
},
|
||||||
|
onResetPassword: (): void => {
|
||||||
|
console.log('onResetPassword');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
public constructor(props: Props, context: State) {
|
||||||
|
super(props, context);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
signinId: '',
|
||||||
|
signinPw: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): JSX.Element {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<TextField
|
||||||
|
hintText='smith@gmail.com'
|
||||||
|
floatingLabelText='Email address*'
|
||||||
|
errorText=''
|
||||||
|
underlineShow={true}
|
||||||
|
value={this.state.signinId}
|
||||||
|
onChange={(e, newValue) => this.setState({ signinId: newValue })}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<TextField
|
||||||
|
hintText='Password'
|
||||||
|
floatingLabelText='Password'
|
||||||
|
type='password'
|
||||||
|
value={this.state.signinPw}
|
||||||
|
onChange={(e, newValue) => this.setState({ signinPw: newValue })}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<RaisedButton
|
||||||
|
label='Sign In'
|
||||||
|
primary={true}
|
||||||
|
onClick={(e) => this.props.onSignin(this.state.signinId, this.state.signinPw)}
|
||||||
|
/>
|
||||||
|
<RaisedButton
|
||||||
|
label='Sign Up'
|
||||||
|
primary={false}
|
||||||
|
onClick={this.props.onSignup}
|
||||||
|
/>
|
||||||
|
<RaisedButton
|
||||||
|
label='Reset Password'
|
||||||
|
primary={false}
|
||||||
|
onClick={this.props.onResetPassword}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
1
src/ts/member/signout/index.ts
Normal file
1
src/ts/member/signout/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from './redux';
|
33
src/ts/member/signout/redux/action/index.ts
Normal file
33
src/ts/member/signout/redux/action/index.ts
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import Action from 'commons/redux/Action';
|
||||||
|
|
||||||
|
import actionTypes from './type';
|
||||||
|
import SignoutPayload from '../payload/SignoutPayload';
|
||||||
|
|
||||||
|
export interface Actions {
|
||||||
|
request: () => Action;
|
||||||
|
requestSuccess: () => Action;
|
||||||
|
requestFailure: (error: Error) => Action;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const actions: Actions = {
|
||||||
|
request(): Action {
|
||||||
|
return {
|
||||||
|
type: actionTypes.REQUEST,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
requestSuccess(): Action {
|
||||||
|
return {
|
||||||
|
type: actionTypes.REQUEST,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
requestFailure(error: Error): Action {
|
||||||
|
return {
|
||||||
|
type: actionTypes.REQUEST,
|
||||||
|
error: error,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default actions;
|
17
src/ts/member/signout/redux/action/type.ts
Normal file
17
src/ts/member/signout/redux/action/type.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
export type REQUEST = '@overflow/member/signout/REQUEST';
|
||||||
|
export type REQUEST_SUCCESS = '@overflow/member/signout/REQUEST_SUCCESS';
|
||||||
|
export type REQUEST_FAILURE = '@overflow/member/signout/REQUEST_FAILURE';
|
||||||
|
|
||||||
|
export interface ActionTypes {
|
||||||
|
REQUEST: REQUEST;
|
||||||
|
REQUEST_SUCCESS: REQUEST_SUCCESS;
|
||||||
|
REQUEST_FAILURE: REQUEST_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const actionTypes: ActionTypes = {
|
||||||
|
REQUEST: '@overflow/member/signout/REQUEST',
|
||||||
|
REQUEST_SUCCESS: '@overflow/member/signout/REQUEST_SUCCESS',
|
||||||
|
REQUEST_FAILURE: '@overflow/member/signout/REQUEST_FAILURE',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default actionTypes;
|
2
src/ts/member/signout/redux/index.ts
Normal file
2
src/ts/member/signout/redux/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './state';
|
||||||
|
export * from './reducer';
|
4
src/ts/member/signout/redux/payload/SignoutPayload.ts
Normal file
4
src/ts/member/signout/redux/payload/SignoutPayload.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
interface SignoutPayload {
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SignoutPayload;
|
21
src/ts/member/signout/redux/reducer/index.ts
Normal file
21
src/ts/member/signout/redux/reducer/index.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import Action from 'commons/redux/Action';
|
||||||
|
import IModule from 'commons/redux/Module';
|
||||||
|
import actionTypes from '../action/type';
|
||||||
|
import State, { defaultState } from '../state';
|
||||||
|
|
||||||
|
|
||||||
|
export function reducer(state: State = defaultState, action: Action): State {
|
||||||
|
switch (action.type) {
|
||||||
|
case actionTypes.REQUEST_SUCCESS:
|
||||||
|
{
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
case actionTypes.REQUEST_FAILURE:
|
||||||
|
{
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
44
src/ts/member/signout/redux/saga/index.ts
Normal file
44
src/ts/member/signout/redux/saga/index.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// import Action from 'commons/redux/Action';
|
||||||
|
// import { SigninPayload } from 'member/signin/redux';
|
||||||
|
// import { takeLatest } from 'redux-saga';
|
||||||
|
// import { call, put } from 'redux-saga/effects';
|
||||||
|
|
||||||
|
// export function * signin(action: Action<SigninPayload>) {
|
||||||
|
// try {
|
||||||
|
// const {signinId, signinPw} = action.payload;
|
||||||
|
// yield put({
|
||||||
|
// type: types.SENDING_REQUEST,
|
||||||
|
// payload: {sendingRequest: true},
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const responseBody = yield call(api.login, signinId, signinPw);
|
||||||
|
|
||||||
|
// if (responseBody.token === undefined) {
|
||||||
|
// throw new Error(MESSAGES.UNABLE_TO_FIND_TOKEN_IN_LOGIN_RESPONSE);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// yield put({
|
||||||
|
// type: types.LOGIN__SUCCEEDED,
|
||||||
|
// payload: {
|
||||||
|
// idToken: responseBody.token,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// } catch (e) {
|
||||||
|
// yield put({
|
||||||
|
// type: types.LOGIN__FAILED,
|
||||||
|
// payload: {
|
||||||
|
// message: e.message,
|
||||||
|
// statusCode: e.statusCode,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// } finally {
|
||||||
|
// yield put({
|
||||||
|
// type: types.SENDING_REQUEST,
|
||||||
|
// payload: {sendingRequest: false},
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export function * watchSignin() {
|
||||||
|
// yield * takeLatest(types.LOGIN__REQUESTED, signin);
|
||||||
|
// }
|
15
src/ts/member/signout/redux/state/index.ts
Normal file
15
src/ts/member/signout/redux/state/index.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import Member from 'member/api/model/Member';
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
isAuthenticated: boolean;
|
||||||
|
member?: Member;
|
||||||
|
error?: Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultState: State = {
|
||||||
|
isAuthenticated: undefined,
|
||||||
|
member: undefined,
|
||||||
|
error: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default State;
|
0
src/ts/member/signout/views/Signin.tsx
Normal file
0
src/ts/member/signout/views/Signin.tsx
Normal file
0
src/ts/member/signout/views/containers/Signin.tsx
Normal file
0
src/ts/member/signout/views/containers/Signin.tsx
Normal file
85
src/ts/member/signout/views/containers/components/Signin.tsx
Normal file
85
src/ts/member/signout/views/containers/components/Signin.tsx
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import * as ReactDOM from 'react-dom';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
Divider,
|
||||||
|
FlatButton,
|
||||||
|
MenuItem,
|
||||||
|
Paper,
|
||||||
|
RaisedButton,
|
||||||
|
SelectField,
|
||||||
|
Slider,
|
||||||
|
TextField,
|
||||||
|
} from 'material-ui';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
onSignin?: (signinId: string, signinPw: string) => void;
|
||||||
|
onSignup?: () => void;
|
||||||
|
onResetPassword?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
signinId: string;
|
||||||
|
signinPw: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Signin extends React.Component<Props, State> {
|
||||||
|
public static defaultProps: Partial<Props> = {
|
||||||
|
onSignin: (signinId: string, signinPw: string): void => {
|
||||||
|
console.log('onSignin');
|
||||||
|
},
|
||||||
|
onSignup: (): void => {
|
||||||
|
console.log('onSignup');
|
||||||
|
},
|
||||||
|
onResetPassword: (): void => {
|
||||||
|
console.log('onResetPassword');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
public constructor(props: Props, context: State) {
|
||||||
|
super(props, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): JSX.Element {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<TextField
|
||||||
|
hintText='smith@gmail.com'
|
||||||
|
floatingLabelText='Email address*'
|
||||||
|
errorText=''
|
||||||
|
underlineShow={true}
|
||||||
|
value={this.state.signinId}
|
||||||
|
onChange={(e, newValue) => this.setState({ signinId: newValue })}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<TextField
|
||||||
|
hintText='Password'
|
||||||
|
floatingLabelText='Password'
|
||||||
|
type='password'
|
||||||
|
value={this.state.signinPw}
|
||||||
|
onChange={(e, newValue) => this.setState({ signinPw: newValue })}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<RaisedButton
|
||||||
|
label='Sign In'
|
||||||
|
primary={true}
|
||||||
|
onClick={(e) => this.props.onSignin(this.state.signinId, this.state.signinPw)}
|
||||||
|
/>
|
||||||
|
<RaisedButton
|
||||||
|
label='Sign Up'
|
||||||
|
primary={false}
|
||||||
|
onClick={this.props.onSignup}
|
||||||
|
/>
|
||||||
|
<RaisedButton
|
||||||
|
label='Reset Password'
|
||||||
|
primary={false}
|
||||||
|
onClick={this.props.onResetPassword}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
1
src/ts/member/signup/index.ts
Normal file
1
src/ts/member/signup/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from './redux';
|
37
src/ts/member/signup/redux/action/index.ts
Normal file
37
src/ts/member/signup/redux/action/index.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import Action from 'commons/redux/Action';
|
||||||
|
|
||||||
|
import Member from 'member/api/model/Member';
|
||||||
|
|
||||||
|
import actionTypes from './type';
|
||||||
|
import SignupPayload from '../payload/SignupPayload';
|
||||||
|
|
||||||
|
export interface Actions {
|
||||||
|
request: (signupPayload: SignupPayload) => Action<SignupPayload>;
|
||||||
|
requestSuccess: (member: Member) => Action<Member>;
|
||||||
|
requestFailure: (error: Error) => Action;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const actions: Actions = {
|
||||||
|
request(signupPayload: SignupPayload): Action<SignupPayload> {
|
||||||
|
return {
|
||||||
|
type: actionTypes.REQUEST,
|
||||||
|
payload: signupPayload,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
requestSuccess(member: Member): Action<Member> {
|
||||||
|
return {
|
||||||
|
type: actionTypes.REQUEST,
|
||||||
|
payload: member,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
requestFailure(error: Error): Action {
|
||||||
|
return {
|
||||||
|
type: actionTypes.REQUEST,
|
||||||
|
error: error,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default actions;
|
17
src/ts/member/signup/redux/action/type.ts
Normal file
17
src/ts/member/signup/redux/action/type.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
export type REQUEST = '@overflow/member/signup/REQUEST';
|
||||||
|
export type REQUEST_SUCCESS = '@overflow/member/signup/REQUEST_SUCCESS';
|
||||||
|
export type REQUEST_FAILURE = '@overflow/member/signup/REQUEST_FAILURE';
|
||||||
|
|
||||||
|
export interface ActionTypes {
|
||||||
|
REQUEST: REQUEST;
|
||||||
|
REQUEST_SUCCESS: REQUEST_SUCCESS;
|
||||||
|
REQUEST_FAILURE: REQUEST_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const actionTypes: ActionTypes = {
|
||||||
|
REQUEST: '@overflow/member/signup/REQUEST',
|
||||||
|
REQUEST_SUCCESS: '@overflow/member/signup/REQUEST_SUCCESS',
|
||||||
|
REQUEST_FAILURE: '@overflow/member/signup/REQUEST_FAILURE',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default actionTypes;
|
2
src/ts/member/signup/redux/index.ts
Normal file
2
src/ts/member/signup/redux/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './state';
|
||||||
|
export * from './reducer';
|
6
src/ts/member/signup/redux/payload/SignupPayload.ts
Normal file
6
src/ts/member/signup/redux/payload/SignupPayload.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import Member from 'member/api/model/Member';
|
||||||
|
|
||||||
|
interface SignupPayload extends Member {
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SignupPayload;
|
24
src/ts/member/signup/redux/reducer/index.ts
Normal file
24
src/ts/member/signup/redux/reducer/index.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import Action from 'commons/redux/Action';
|
||||||
|
import IModule from 'commons/redux/Module';
|
||||||
|
|
||||||
|
import Member from 'member/api/model/Member';
|
||||||
|
|
||||||
|
import actionTypes from '../action/type';
|
||||||
|
import State, { defaultState } from '../state';
|
||||||
|
|
||||||
|
|
||||||
|
export function reducer(state: State = defaultState, action: Action<Member | Error>): State {
|
||||||
|
switch (action.type) {
|
||||||
|
case actionTypes.REQUEST_SUCCESS:
|
||||||
|
{
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
case actionTypes.REQUEST_FAILURE:
|
||||||
|
{
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
44
src/ts/member/signup/redux/saga/index.ts
Normal file
44
src/ts/member/signup/redux/saga/index.ts
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// import Action from 'commons/redux/Action';
|
||||||
|
// import { SigninPayload } from 'member/signin/redux';
|
||||||
|
// import { takeLatest } from 'redux-saga';
|
||||||
|
// import { call, put } from 'redux-saga/effects';
|
||||||
|
|
||||||
|
// export function * signin(action: Action<SigninPayload>) {
|
||||||
|
// try {
|
||||||
|
// const {signinId, signinPw} = action.payload;
|
||||||
|
// yield put({
|
||||||
|
// type: types.SENDING_REQUEST,
|
||||||
|
// payload: {sendingRequest: true},
|
||||||
|
// });
|
||||||
|
|
||||||
|
// const responseBody = yield call(api.login, signinId, signinPw);
|
||||||
|
|
||||||
|
// if (responseBody.token === undefined) {
|
||||||
|
// throw new Error(MESSAGES.UNABLE_TO_FIND_TOKEN_IN_LOGIN_RESPONSE);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// yield put({
|
||||||
|
// type: types.LOGIN__SUCCEEDED,
|
||||||
|
// payload: {
|
||||||
|
// idToken: responseBody.token,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// } catch (e) {
|
||||||
|
// yield put({
|
||||||
|
// type: types.LOGIN__FAILED,
|
||||||
|
// payload: {
|
||||||
|
// message: e.message,
|
||||||
|
// statusCode: e.statusCode,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// } finally {
|
||||||
|
// yield put({
|
||||||
|
// type: types.SENDING_REQUEST,
|
||||||
|
// payload: {sendingRequest: false},
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export function * watchSignin() {
|
||||||
|
// yield * takeLatest(types.LOGIN__REQUESTED, signin);
|
||||||
|
// }
|
15
src/ts/member/signup/redux/state/index.ts
Normal file
15
src/ts/member/signup/redux/state/index.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import Member from 'member/api/model/Member';
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
isRegistered: boolean;
|
||||||
|
member?: Member;
|
||||||
|
error?: Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const defaultState: State = {
|
||||||
|
isRegistered: undefined,
|
||||||
|
member: undefined,
|
||||||
|
error: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default State;
|
0
src/ts/member/signup/views/Signin.tsx
Normal file
0
src/ts/member/signup/views/Signin.tsx
Normal file
0
src/ts/member/signup/views/containers/Signin.tsx
Normal file
0
src/ts/member/signup/views/containers/Signin.tsx
Normal file
85
src/ts/member/signup/views/containers/components/Signin.tsx
Normal file
85
src/ts/member/signup/views/containers/components/Signin.tsx
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import * as ReactDOM from 'react-dom';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
Divider,
|
||||||
|
FlatButton,
|
||||||
|
MenuItem,
|
||||||
|
Paper,
|
||||||
|
RaisedButton,
|
||||||
|
SelectField,
|
||||||
|
Slider,
|
||||||
|
TextField,
|
||||||
|
} from 'material-ui';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
onSignin?: (signinId: string, signinPw: string) => void;
|
||||||
|
onSignup?: () => void;
|
||||||
|
onResetPassword?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface State {
|
||||||
|
signinId: string;
|
||||||
|
signinPw: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Signin extends React.Component<Props, State> {
|
||||||
|
public static defaultProps: Partial<Props> = {
|
||||||
|
onSignin: (signinId: string, signinPw: string): void => {
|
||||||
|
console.log('onSignin');
|
||||||
|
},
|
||||||
|
onSignup: (): void => {
|
||||||
|
console.log('onSignup');
|
||||||
|
},
|
||||||
|
onResetPassword: (): void => {
|
||||||
|
console.log('onResetPassword');
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
public constructor(props: Props, context: State) {
|
||||||
|
super(props, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): JSX.Element {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<TextField
|
||||||
|
hintText='smith@gmail.com'
|
||||||
|
floatingLabelText='Email address*'
|
||||||
|
errorText=''
|
||||||
|
underlineShow={true}
|
||||||
|
value={this.state.signinId}
|
||||||
|
onChange={(e, newValue) => this.setState({ signinId: newValue })}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<TextField
|
||||||
|
hintText='Password'
|
||||||
|
floatingLabelText='Password'
|
||||||
|
type='password'
|
||||||
|
value={this.state.signinPw}
|
||||||
|
onChange={(e, newValue) => this.setState({ signinPw: newValue })}
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<RaisedButton
|
||||||
|
label='Sign In'
|
||||||
|
primary={true}
|
||||||
|
onClick={(e) => this.props.onSignin(this.state.signinId, this.state.signinPw)}
|
||||||
|
/>
|
||||||
|
<RaisedButton
|
||||||
|
label='Sign Up'
|
||||||
|
primary={false}
|
||||||
|
onClick={this.props.onSignup}
|
||||||
|
/>
|
||||||
|
<RaisedButton
|
||||||
|
label='Reset Password'
|
||||||
|
primary={false}
|
||||||
|
onClick={this.props.onResetPassword}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user