diff --git a/package.json b/package.json index b085bfa..039c857 100644 --- a/package.json +++ b/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" }, "devDependencies": { + "@types/auth0-lock": "^10.16.0", + "@types/history": "^4.6.0", "@types/jest": "^19.2.4", "@types/material-ui": "^0.17.11", "@types/prop-types": "^15.5.1", - "@types/react": "^15.0.24", - "@types/react-addons-test-utils": "^0.14.18", - "@types/react-dom": "^15.5.0", - "@types/react-redux": "4.4.40", - "@types/react-router": "^4.0.9", - "@types/react-router-dom": "^4.0.4", + "@types/react": "^15.0.32", + "@types/react-addons-test-utils": "^0.14.19", + "@types/react-dom": "^15.5.1", + "@types/react-redux": "^4.4.45", + "@types/react-router": "^4.0.12", + "@types/react-router-dom": "^4.0.5", + "@types/react-router-redux": "^5.0.3", "@types/react-tap-event-plugin": "^0.0.30", "@types/redux": "^3.6.0", "@types/redux-actions": "^1.2.6", @@ -62,22 +65,24 @@ "webpack-visualizer-plugin": "^0.1.11" }, "dependencies": { + "auth0-lock": "^10.18.0", + "history": "^4.6.3", "immutable": "^3.8.1", "material-ui": "^0.18.3", - "prop-types":"^15.5.10", - "react": "^15.5.4", - "react-dom": "15.5.4", + "prop-types": "^15.5.10", + "react": "^15.6.1", + "react-dom": "^15.6.1", "react-immutable-proptypes": "^2.1.0", "react-redux": "^5.0.5", "react-router": "^4.1.1", "react-router-dom": "^4.1.1", + "react-router-redux": "next", "react-tap-event-plugin": "^2.0.1", - "redux": "^3.6.0", + "redux": "^3.7.1", "redux-actions": "^2.0.3", - "redux-saga": "^0.15.3", + "redux-saga": "^0.15.4", "reselect": "^3.0.1" }, - "jest": { "moduleFileExtensions": [ "ts", diff --git a/src/ts/app/views/container/component/App.tsx b/src/ts/app/views/container/component/App.tsx new file mode 100644 index 0000000..ae2843c --- /dev/null +++ b/src/ts/app/views/container/component/App.tsx @@ -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 { + public constructor(props: Props, context: State) { + super(props, context); + } + + public render(): JSX.Element { + + return ( +
+ + + +
+ ); + } +} diff --git a/src/ts/commons/module/Module.ts b/src/ts/commons/module/Module.ts new file mode 100644 index 0000000..de4e80e --- /dev/null +++ b/src/ts/commons/module/Module.ts @@ -0,0 +1,8 @@ +interface IModule { + components: IComponentType; + containers: IContainerType; + views: IViewType; + redux: IReduxType; +} + +export default IModule; diff --git a/src/ts/commons/redux/Action.ts b/src/ts/commons/redux/Action.ts index 1583241..6eb49fe 100644 --- a/src/ts/commons/redux/Action.ts +++ b/src/ts/commons/redux/Action.ts @@ -1,8 +1,8 @@ -interface Action { - type: any; +import * as Redux from 'redux'; + +interface Action extends Redux.Action { payload?: Payload; error?: Error; } - export default Action; diff --git a/src/ts/commons/redux/Module.ts b/src/ts/commons/redux/Module.ts index 8671bc3..e1d4d79 100644 --- a/src/ts/commons/redux/Module.ts +++ b/src/ts/commons/redux/Module.ts @@ -1,10 +1,8 @@ import Action from './Action'; -interface IModule { - Name: string; - ActionTypes: {[key: string]: any}; - Actions: {[key: string]: any}; - Reducer: (state: State, action: Action) => State; +export interface IModule { + state: State; + reducer: (state: State, action: Action) => State; } export default IModule; diff --git a/src/ts/commons/util/immutable/Record.ts b/src/ts/commons/util/immutable/Record.ts deleted file mode 100644 index 08fd0cf..0000000 --- a/src/ts/commons/util/immutable/Record.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Iterable, Map, Record as ImmutableRecord } from 'immutable'; - -export interface Record> extends Map { - 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, value: any) => T; - deleteIn: (keyPath: Array | Iterable) => T; - removeIn: (keyPath: Array | Iterable) => T; - updateIn: { - (keyPath: any[] | Iterable, updater: (value: any) => any): T; - ( - keyPath: any[] | Iterable, - notSetValue: any, - updater: (value: any) => any, - ): T - }; - mergeIn: (keyPath: any[] | Iterable, obj: any) => T; - mergeDeepIn: (keyPath: any[] | Iterable, obj: any) => T; - withMutations: (mutator: (mutable: T) => any) => T; - asMutable: () => T; - asImmutable: () => T; -} - -export function makeRecordType & O> - (defaultVal: O, val: O = null, name?: string): R { - - const RecordFactory = makeRecordFactory(defaultVal, name); - return val ? RecordFactory(val) : RecordFactory(); -} - -export function makeRecordFactory & O> - (obj: O, name?: string): (val?: O) => R { - - const iRecord = ImmutableRecord(obj, name); - return (val: O = null) => { - return new iRecord(val) as R; - }; -} diff --git a/src/ts/commons/util/system/index.ts b/src/ts/commons/util/system/index.ts new file mode 100644 index 0000000..4debd13 --- /dev/null +++ b/src/ts/commons/util/system/index.ts @@ -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; +} diff --git a/src/ts/config/configureMuiTheme.ts b/src/ts/config/configureMuiTheme.ts new file mode 100644 index 0000000..7e890fd --- /dev/null +++ b/src/ts/config/configureMuiTheme.ts @@ -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; diff --git a/src/ts/config/configureRedux.ts b/src/ts/config/configureRedux.ts new file mode 100644 index 0000000..da144d5 --- /dev/null +++ b/src/ts/config/configureRedux.ts @@ -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({ + member: Member.reducer, + router: routerReducer, +}); diff --git a/src/ts/config/configureRouter.tsx b/src/ts/config/configureRouter.tsx new file mode 100644 index 0000000..139597f --- /dev/null +++ b/src/ts/config/configureRouter.tsx @@ -0,0 +1,2 @@ + + diff --git a/src/ts/config/configureStore.ts b/src/ts/config/configureStore.ts new file mode 100644 index 0000000..b8d3e3b --- /dev/null +++ b/src/ts/config/configureStore.ts @@ -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): Store { + const middlewares = [sagaMiddleware, routerMiddleware(history)]; + const store = createStore( + reducer, + applyMiddleware(...middlewares), + ); + + // sagaMiddleware.run(rootSaga); + + return store; +} diff --git a/src/ts/index.tsx b/src/ts/index.tsx index d9cfe1e..281f2d0 100644 --- a/src/ts/index.tsx +++ b/src/ts/index.tsx @@ -1,32 +1,56 @@ -import * as member from 'member/redux'; -import { Action, createStore, combineReducers } from 'redux'; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import createSagaMiddleware, { SagaMiddleware } from 'redux-saga'; +import { createHashHistory } from 'history'; -export interface StateRecord { - member: member.StateRecord; +import { Provider } from 'react-redux'; +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 = createSagaMiddleware(); + +const history = createHashHistory(); +const store = configureStore(history, sagaMiddleware); + +function* app(): any { + const appContainer = yield system.getAppContainer('react-placeholder'); + + ReactDOM.render( +
+

Loading...

+
, + appContainer, + ); + + + ReactDOM.render( + + + + + + + , + appContainer, + ); } -export interface IActionTypes { - 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({ - member: member.Reducers, -}); - - -let store = createStore(Reducers); - -console.log(''); +sagaMiddleware.run(app); diff --git a/src/ts/member/api/model/Member.ts b/src/ts/member/api/model/Member.ts index ea24213..43b400f 100644 --- a/src/ts/member/api/model/Member.ts +++ b/src/ts/member/api/model/Member.ts @@ -1,7 +1,7 @@ import {MemberStatus} from './MemberStatus'; -export interface Member { +interface Member { id?: number; email: string; name: string; @@ -10,3 +10,5 @@ export interface Member { createDate?: Date; status?: MemberStatus; } + +export default Member; diff --git a/src/ts/member/index.ts b/src/ts/member/index.ts new file mode 100644 index 0000000..761baae --- /dev/null +++ b/src/ts/member/index.ts @@ -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({ + signin: signin.reducer, + signout: signout.reducer, + signup: signup.reducer, +}); diff --git a/src/ts/member/redux/index.ts b/src/ts/member/redux/index.ts deleted file mode 100644 index ecf3573..0000000 --- a/src/ts/member/redux/index.ts +++ /dev/null @@ -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({ - signin: signin.Reducers, - signout: signout.Reducers, - signup: signup.Reducers, -}); - diff --git a/src/ts/member/redux/signin/index.ts b/src/ts/member/redux/signin/index.ts deleted file mode 100644 index afddc98..0000000 --- a/src/ts/member/redux/signin/index.ts +++ /dev/null @@ -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, State { -} - -const makeStateRecord = makeRecordFactory({ - 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; - requestSuccess: (member: Member) => Action; - requestFailure: (error: Error) => Action; -} -export const Actions: IActions = { - request(signinId: string, signinPw: string): Action { - return { - type: ActionTypes.REQUEST, - payload: { - signinId: signinId, - signinPw: signinPw, - }, - }; - }, - - requestSuccess(member: Member): Action { - return { - type: ActionTypes.REQUEST, - payload: member, - }; - }, - - 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; - } -} diff --git a/src/ts/member/redux/signout/index.ts b/src/ts/member/redux/signout/index.ts deleted file mode 100644 index 487fc43..0000000 --- a/src/ts/member/redux/signout/index.ts +++ /dev/null @@ -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, State { -} - -const makeStateRecord = makeRecordFactory({ -}); - - -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; - } -} diff --git a/src/ts/member/redux/signup/index.ts b/src/ts/member/redux/signup/index.ts deleted file mode 100644 index 0f7677c..0000000 --- a/src/ts/member/redux/signup/index.ts +++ /dev/null @@ -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, State { -} - -const makeStateRecord = makeRecordFactory({ - 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; - requestSuccess: (member: Member) => Action; - requestFailure: (error: Error) => Action; -} -export const Actions: IActions = { - request(member: Member): Action { - return { - type: ActionTypes.REQUEST, - payload: member, - }; - }, - - requestSuccess(member: Member): Action { - return { - type: ActionTypes.REQUEST, - payload: member, - }; - }, - - 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({isRegistered: true, member: action.payload}); - } - case ActionTypes.REQUEST_FAILURE: - { - return state.merge({isRegistered: false, error: action.error}); - } - default: - return state; - } -} diff --git a/src/ts/member/signin/index.ts b/src/ts/member/signin/index.ts new file mode 100644 index 0000000..9686012 --- /dev/null +++ b/src/ts/member/signin/index.ts @@ -0,0 +1 @@ +export * from './redux'; diff --git a/src/ts/member/signin/redux/action/index.ts b/src/ts/member/signin/redux/action/index.ts new file mode 100644 index 0000000..3eff1e8 --- /dev/null +++ b/src/ts/member/signin/redux/action/index.ts @@ -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; + requestSuccess: (member: Member) => Action; + requestFailure: (error: Error) => Action; +} + +export const actions: Actions = { + request(signinId: string, signinPw: string): Action { + return { + type: actionTypes.REQUEST, + payload: { + signinId: signinId, + signinPw: signinPw, + }, + }; + }, + + requestSuccess(member: Member): Action { + return { + type: actionTypes.REQUEST, + payload: member, + }; + }, + + requestFailure(error: Error): Action { + return { + type: actionTypes.REQUEST, + error: error, + }; + }, +}; + +export default actions; diff --git a/src/ts/member/signin/redux/action/type.ts b/src/ts/member/signin/redux/action/type.ts new file mode 100644 index 0000000..79ce1c7 --- /dev/null +++ b/src/ts/member/signin/redux/action/type.ts @@ -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; diff --git a/src/ts/member/signin/redux/index.ts b/src/ts/member/signin/redux/index.ts new file mode 100644 index 0000000..34d7d96 --- /dev/null +++ b/src/ts/member/signin/redux/index.ts @@ -0,0 +1,2 @@ +export * from './state'; +export * from './reducer'; diff --git a/src/ts/member/signin/redux/payload/SigninPayload.ts b/src/ts/member/signin/redux/payload/SigninPayload.ts new file mode 100644 index 0000000..3a997b2 --- /dev/null +++ b/src/ts/member/signin/redux/payload/SigninPayload.ts @@ -0,0 +1,6 @@ +interface SigninPayload { + signinId: string; + signinPw: string; +} + +export default SigninPayload; diff --git a/src/ts/member/signin/redux/reducer/index.ts b/src/ts/member/signin/redux/reducer/index.ts new file mode 100644 index 0000000..89dfca9 --- /dev/null +++ b/src/ts/member/signin/redux/reducer/index.ts @@ -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): State { + switch (action.type) { + case actionTypes.REQUEST_SUCCESS: + { + + return state; + } + case actionTypes.REQUEST_FAILURE: + { + return state; + } + default: + return state; + } +} diff --git a/src/ts/member/signin/redux/saga/index.ts b/src/ts/member/signin/redux/saga/index.ts new file mode 100644 index 0000000..3deb814 --- /dev/null +++ b/src/ts/member/signin/redux/saga/index.ts @@ -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): 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); +} diff --git a/src/ts/member/signin/redux/state/index.ts b/src/ts/member/signin/redux/state/index.ts new file mode 100644 index 0000000..5ddc23b --- /dev/null +++ b/src/ts/member/signin/redux/state/index.ts @@ -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; diff --git a/src/ts/member/signin/views/Signin.tsx b/src/ts/member/signin/views/Signin.tsx new file mode 100644 index 0000000..64b3ef1 --- /dev/null +++ b/src/ts/member/signin/views/Signin.tsx @@ -0,0 +1,14 @@ +import * as React from 'react'; +import { RouteComponentProps } from 'react-router'; +import SigninContainer from './containers/Signin'; + +class Signin extends React.Component, object> { + public render(): JSX.Element { + return ( + + ); + } +} + + +export default Signin; diff --git a/src/ts/member/signin/views/containers/Signin.tsx b/src/ts/member/signin/views/containers/Signin.tsx new file mode 100644 index 0000000..3fa9cb3 --- /dev/null +++ b/src/ts/member/signin/views/containers/Signin.tsx @@ -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): SigninProps { + return { + onSignin: (signinId: string, signinPw: string) => { + dispatch(signinActions.request(signinId, signinPw)); + }, + onSignup: () => { + return; + }, + onResetPassword: () => { + return; + }, + }; +} + +export default connect(mapStateToProps, mapDispatchToProps)(Signin); diff --git a/src/ts/member/signin/views/containers/components/Signin.tsx b/src/ts/member/signin/views/containers/components/Signin.tsx new file mode 100644 index 0000000..b53aa05 --- /dev/null +++ b/src/ts/member/signin/views/containers/components/Signin.tsx @@ -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 { + public static defaultProps: Partial = { + 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 ( +
+ this.setState({ signinId: newValue })} + /> +
+ this.setState({ signinPw: newValue })} + /> +
+ + this.props.onSignin(this.state.signinId, this.state.signinPw)} + /> + + + +
+ ); + } +} diff --git a/src/ts/member/signout/index.ts b/src/ts/member/signout/index.ts new file mode 100644 index 0000000..9686012 --- /dev/null +++ b/src/ts/member/signout/index.ts @@ -0,0 +1 @@ +export * from './redux'; diff --git a/src/ts/member/signout/redux/action/index.ts b/src/ts/member/signout/redux/action/index.ts new file mode 100644 index 0000000..d9ef053 --- /dev/null +++ b/src/ts/member/signout/redux/action/index.ts @@ -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; diff --git a/src/ts/member/signout/redux/action/type.ts b/src/ts/member/signout/redux/action/type.ts new file mode 100644 index 0000000..99769a7 --- /dev/null +++ b/src/ts/member/signout/redux/action/type.ts @@ -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; diff --git a/src/ts/member/signout/redux/index.ts b/src/ts/member/signout/redux/index.ts new file mode 100644 index 0000000..34d7d96 --- /dev/null +++ b/src/ts/member/signout/redux/index.ts @@ -0,0 +1,2 @@ +export * from './state'; +export * from './reducer'; diff --git a/src/ts/member/signout/redux/payload/SignoutPayload.ts b/src/ts/member/signout/redux/payload/SignoutPayload.ts new file mode 100644 index 0000000..43ba490 --- /dev/null +++ b/src/ts/member/signout/redux/payload/SignoutPayload.ts @@ -0,0 +1,4 @@ +interface SignoutPayload { +} + +export default SignoutPayload; diff --git a/src/ts/member/signout/redux/reducer/index.ts b/src/ts/member/signout/redux/reducer/index.ts new file mode 100644 index 0000000..b778369 --- /dev/null +++ b/src/ts/member/signout/redux/reducer/index.ts @@ -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; + } +} diff --git a/src/ts/member/signout/redux/saga/index.ts b/src/ts/member/signout/redux/saga/index.ts new file mode 100644 index 0000000..3046f88 --- /dev/null +++ b/src/ts/member/signout/redux/saga/index.ts @@ -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) { +// 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); +// } diff --git a/src/ts/member/signout/redux/state/index.ts b/src/ts/member/signout/redux/state/index.ts new file mode 100644 index 0000000..5ddc23b --- /dev/null +++ b/src/ts/member/signout/redux/state/index.ts @@ -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; diff --git a/src/ts/member/signout/views/Signin.tsx b/src/ts/member/signout/views/Signin.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/ts/member/signout/views/containers/Signin.tsx b/src/ts/member/signout/views/containers/Signin.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/ts/member/signout/views/containers/components/Signin.tsx b/src/ts/member/signout/views/containers/components/Signin.tsx new file mode 100644 index 0000000..2a059b4 --- /dev/null +++ b/src/ts/member/signout/views/containers/components/Signin.tsx @@ -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 { + public static defaultProps: Partial = { + 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 ( +
+ this.setState({ signinId: newValue })} + /> +
+ this.setState({ signinPw: newValue })} + /> +
+ + this.props.onSignin(this.state.signinId, this.state.signinPw)} + /> + + + +
+ ); + } +} diff --git a/src/ts/member/signup/index.ts b/src/ts/member/signup/index.ts new file mode 100644 index 0000000..9686012 --- /dev/null +++ b/src/ts/member/signup/index.ts @@ -0,0 +1 @@ +export * from './redux'; diff --git a/src/ts/member/signup/redux/action/index.ts b/src/ts/member/signup/redux/action/index.ts new file mode 100644 index 0000000..e612a63 --- /dev/null +++ b/src/ts/member/signup/redux/action/index.ts @@ -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; + requestSuccess: (member: Member) => Action; + requestFailure: (error: Error) => Action; +} + +export const actions: Actions = { + request(signupPayload: SignupPayload): Action { + return { + type: actionTypes.REQUEST, + payload: signupPayload, + }; + }, + + requestSuccess(member: Member): Action { + return { + type: actionTypes.REQUEST, + payload: member, + }; + }, + + requestFailure(error: Error): Action { + return { + type: actionTypes.REQUEST, + error: error, + }; + }, +}; + +export default actions; diff --git a/src/ts/member/signup/redux/action/type.ts b/src/ts/member/signup/redux/action/type.ts new file mode 100644 index 0000000..80c2218 --- /dev/null +++ b/src/ts/member/signup/redux/action/type.ts @@ -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; diff --git a/src/ts/member/signup/redux/index.ts b/src/ts/member/signup/redux/index.ts new file mode 100644 index 0000000..34d7d96 --- /dev/null +++ b/src/ts/member/signup/redux/index.ts @@ -0,0 +1,2 @@ +export * from './state'; +export * from './reducer'; diff --git a/src/ts/member/signup/redux/payload/SignupPayload.ts b/src/ts/member/signup/redux/payload/SignupPayload.ts new file mode 100644 index 0000000..82963c0 --- /dev/null +++ b/src/ts/member/signup/redux/payload/SignupPayload.ts @@ -0,0 +1,6 @@ +import Member from 'member/api/model/Member'; + +interface SignupPayload extends Member { +} + +export default SignupPayload; diff --git a/src/ts/member/signup/redux/reducer/index.ts b/src/ts/member/signup/redux/reducer/index.ts new file mode 100644 index 0000000..89dfca9 --- /dev/null +++ b/src/ts/member/signup/redux/reducer/index.ts @@ -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): State { + switch (action.type) { + case actionTypes.REQUEST_SUCCESS: + { + + return state; + } + case actionTypes.REQUEST_FAILURE: + { + return state; + } + default: + return state; + } +} diff --git a/src/ts/member/signup/redux/saga/index.ts b/src/ts/member/signup/redux/saga/index.ts new file mode 100644 index 0000000..3046f88 --- /dev/null +++ b/src/ts/member/signup/redux/saga/index.ts @@ -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) { +// 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); +// } diff --git a/src/ts/member/signup/redux/state/index.ts b/src/ts/member/signup/redux/state/index.ts new file mode 100644 index 0000000..06e31a6 --- /dev/null +++ b/src/ts/member/signup/redux/state/index.ts @@ -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; diff --git a/src/ts/member/signup/views/Signin.tsx b/src/ts/member/signup/views/Signin.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/ts/member/signup/views/containers/Signin.tsx b/src/ts/member/signup/views/containers/Signin.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/ts/member/signup/views/containers/components/Signin.tsx b/src/ts/member/signup/views/containers/components/Signin.tsx new file mode 100644 index 0000000..2a059b4 --- /dev/null +++ b/src/ts/member/signup/views/containers/components/Signin.tsx @@ -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 { + public static defaultProps: Partial = { + 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 ( +
+ this.setState({ signinId: newValue })} + /> +
+ this.setState({ signinPw: newValue })} + /> +
+ + this.props.onSignin(this.state.signinId, this.state.signinPw)} + /> + + + +
+ ); + } +}