Skip to content
This repository has been archived by the owner on May 11, 2021. It is now read-only.

Commit

Permalink
feat(user): add login stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
igorkamyshev committed Feb 11, 2019
1 parent ca29e62 commit 12955e4
Show file tree
Hide file tree
Showing 15 changed files with 158 additions and 11 deletions.
1 change: 1 addition & 0 deletions front/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"react-dom": "^16.7.0",
"react-redux": "^6.0.0",
"redux": "^4.0.1",
"redux-clear": "^1.0.3",
"redux-devtools-extension": "^2.13.7",
"redux-thunk": "^2.3.0"
},
Expand Down
4 changes: 2 additions & 2 deletions front/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Option } from 'tsoption'
import { AppContext } from '@front/domain/AppContext'
import { WithReduxProps } from '@front/domain/store/WithReduxProps'
import { withReduxStore } from '@front/domain/store/withReduxStore'
import { actions } from '@front/domain/user/reducer/data'

class CheckmoneyWeb extends App<WithReduxProps> {
public static getInitialProps(appContext: NextAppContext) {
Expand All @@ -18,8 +19,7 @@ class CheckmoneyWeb extends App<WithReduxProps> {
.map(cookies => cookies.token)

if (token.nonEmpty()) {
// TODO:
// ctx.reduxStore.dispatch(setToken(token))
ctx.reduxStore.dispatch(actions.setToken(token.get()))
}

return App.getInitialProps(appContext)
Expand Down
4 changes: 3 additions & 1 deletion front/src/domain/store/State.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { State as UserState } from '@front/domain/user/reducer'

export interface State {
a: string // TODO: remove
user: UserState
}
7 changes: 6 additions & 1 deletion front/src/domain/store/getOrCreateStore.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { initializeStore } from './initializeStore'
import { State } from './State'
import actualizeStore from './utils/actualizeStore'
import { actualizeStore } from './utils/actualizeStore'
import { markOptions } from './utils/markOptions'

const isServer = typeof window === 'undefined'
const __NEXT_REDUX_STORE__ = '__NEXT_REDUX_STORE__'

export const getOrCreateStore = (initialState?: State) => {
if (isServer) {
markOptions(initialState)
}

const state = actualizeStore(initialState)

// Always make a new store if server, otherwise state is shared between requests
Expand Down
8 changes: 7 additions & 1 deletion front/src/domain/store/reducer.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import { combineReducers } from 'redux'

import { reducer as userReducer } from '@front/domain/user/reducer'

import { State } from './State'

export const reducer = (s: State | undefined) => s as State
export const reducer = combineReducers<State>({
user: userReducer,
})
19 changes: 13 additions & 6 deletions front/src/domain/store/utils/actualizeStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,31 @@ import {
mapValues,
} from 'lodash'

import { tapDate } from './taps/tapDate'
import { ObjectTaper } from './objectTaps/ObjectTaper'
import { OptionTaper } from './objectTaps/OptionTaper'
import { tapDate } from './stringTaps/tapDate'

const TAPS = [tapDate]
const STRING_TAPS = [tapDate]
const OBJECT_TAPERS: ObjectTaper[] = [new OptionTaper()]

const actualizeStore = (data: any): any => {
export const actualizeStore = (data: any): any => {
if (isArray(data)) {
return data.map(actualizeStore)
}

if (isString(data)) {
return flow(TAPS)(data)
return flow(STRING_TAPS)(data)
}

if (isUndefined(data) || !isPlainObject(data)) {
return data
}

const supportedTapers = OBJECT_TAPERS.filter(taper => taper.supports(data))

if (isPlainObject(data) && supportedTapers.length > 0) {
return flow(supportedTapers.map(taper => (v: any) => taper.tap(v)))(data)
}

return mapValues(data, value => actualizeStore(value))
}

export default actualizeStore
20 changes: 20 additions & 0 deletions front/src/domain/store/utils/markOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { isObject, mapValues } from 'lodash'
import { Option } from 'tsoption'

import { OPTION_MARK } from './objectTaps/OPTION_MARK'

const mapValuesDeep = (obj: any, callback: (value: any) => any): any =>
isObject(obj) && !isOption(obj)
? mapValues(obj, (value: any) => mapValuesDeep(value, callback))
: callback(obj)

const isOption = (obj: any): boolean => obj instanceof Option

export const markOptions = (obj: any) =>
mapValuesDeep(obj, (v: any) => {
if (isOption(v)) {
v[OPTION_MARK] = true
}

return v
})
1 change: 1 addition & 0 deletions front/src/domain/store/utils/objectTaps/OPTION_MARK.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const OPTION_MARK = '__OPTION_MARK__'
4 changes: 4 additions & 0 deletions front/src/domain/store/utils/objectTaps/ObjectTaper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface ObjectTaper {
supports(object: any): boolean
tap(object: any): any
}
14 changes: 14 additions & 0 deletions front/src/domain/store/utils/objectTaps/OptionTaper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Option } from 'tsoption'

import { ObjectTaper } from './ObjectTaper'
import { OPTION_MARK } from './OPTION_MARK'

export class OptionTaper implements ObjectTaper {
public supports(object: any): boolean {
return !!object[OPTION_MARK]
}

public tap(object: any) {
return Option.of(object.value)
}
}
25 changes: 25 additions & 0 deletions front/src/domain/user/reducer/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ClearAction, createClearRedux } from 'redux-clear'
import { Option } from 'tsoption'

interface State {
token: Option<string>
}

interface Actions {
setToken: ClearAction<[string]>
}

const { reducer, actions } = createClearRedux<State, Actions>(
{
setToken: state => token => ({
...state,
token: Option.of(token),
}),
},
{
token: Option.of(null),
},
'user',
)

export { reducer, actions, State }
16 changes: 16 additions & 0 deletions front/src/domain/user/reducer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { combineReducers } from 'redux'

import { reducer as dataReducer, State as DataState } from './data'
import { reducer as signInReducer, State as SignInState } from './signIn'

interface State {
signIn: SignInState
data: DataState
}

const reducer = combineReducers<State>({
signIn: signInReducer,
data: dataReducer,
})

export { reducer, State }
34 changes: 34 additions & 0 deletions front/src/domain/user/reducer/signIn.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ClearAction, createClearRedux } from 'redux-clear'
import { Option } from 'tsoption'

interface State {
error: Option<string>
loading: boolean
}

interface Actions {
request: ClearAction
failure: ClearAction<[string]>
}

const { reducer, actions } = createClearRedux<State, Actions>(
{
request: state => () => ({
...state,
error: Option.of(null),
loading: true,
}),
failure: state => error => ({
...state,
error: Option.of(error),
loading: false,
}),
},
{
loading: false,
error: Option.of(null),
},
'user',
)

export { reducer, actions, State }
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6303,6 +6303,11 @@ nanoid@1.2.1:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-1.2.1.tgz#922bf6c10e35f7b208993768dad643577c907adf"
integrity sha512-S1QSG+TQtsqr2/ujHZcNT0OxygffUaUT755qTc/SPKfQ0VJBlOO6qb1425UYoHXPvCZ3pWgMVCuy1t7+AoCxnQ==

nanoid@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-2.0.1.tgz#deb55cac196e3f138071911dabbc3726eb048864"
integrity sha512-k1u2uemjIGsn25zmujKnotgniC/gxQ9sdegdezeDiKdkDW56THUMqlz3urndKCXJxA6yPzSZbXx/QCMe/pxqsA==

nanomatch@^1.2.9:
version "1.2.13"
resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119"
Expand Down Expand Up @@ -8169,6 +8174,13 @@ redent@^2.0.0:
indent-string "^3.0.0"
strip-indent "^2.0.0"

redux-clear@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/redux-clear/-/redux-clear-1.0.3.tgz#7881e8c7157f81e8a21866a946cd87dcfcc6ce49"
integrity sha512-9iRFRcHvCrjpp+3cwVhxookErW8vHgfnFDmvd8VEUUqKXRaHc8VXs66USv4V2jqNxHaAZ1hg164Bk04EE9RBmg==
dependencies:
nanoid "^2.0.1"

redux-devtools-extension@^2.13.7:
version "2.13.7"
resolved "https://registry.yarnpkg.com/redux-devtools-extension/-/redux-devtools-extension-2.13.7.tgz#14bd7a1a7c8bee7f397beb1116fd16fc9633b752"
Expand Down

0 comments on commit 12955e4

Please sign in to comment.