Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
Agiliza
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
evologica
Agiliza
Commits
06b6c363
Commit
06b6c363
authored
Aug 09, 2021
by
Rafael
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adiciona conexões com o serviço e primeiro acesso no simulador.
parent
533c4f22
Changes
138
Hide whitespace changes
Inline
Side-by-side
Showing
138 changed files
with
2915 additions
and
807 deletions
+2915
-807
.yarnrc
cli/web/.yarnrc
+1
-1
babel.config.json
cli/web/babel.config.json
+3
-9
dev.json
cli/web/config/dev.json
+5
-14
env.json
cli/web/config/env.json
+7
-0
prod.json
cli/web/config/prod.json
+5
-14
staging.json
cli/web/config/staging.json
+5
-14
package.json
cli/web/package.json
+1
-0
config.json
cli/web/public/config.json
+5
-14
server.js
cli/web/server.js
+2
-2
firstAccess.d.ts
cli/web/src/api/domain/authentication/firstAccess.d.ts
+93
-0
index.d.ts
cli/web/src/api/domain/authentication/index.d.ts
+1
-0
context.d.ts
cli/web/src/api/domain/context.d.ts
+11
-0
error.d.ts
cli/web/src/api/domain/error.d.ts
+78
-0
index.d.ts
cli/web/src/api/domain/index.d.ts
+17
-0
index.ts
cli/web/src/api/domain/index.ts
+0
-1
index.d.ts
cli/web/src/api/domain/proposalData/index.d.ts
+0
-0
context.d.ts
cli/web/src/api/domain/simulation/context.d.ts
+23
-0
index.d.ts
cli/web/src/api/domain/simulation/index.d.ts
+2
-0
simulation.d.ts
cli/web/src/api/domain/simulation/simulation.d.ts
+30
-0
index.ts
cli/web/src/api/dynamo/index.ts
+0
-25
index.ts
cli/web/src/api/index.ts
+28
-0
authentication.ts
cli/web/src/api/mappers/api/authentication.ts
+29
-0
index.ts
cli/web/src/api/mappers/api/index.ts
+5
-0
session.ts
cli/web/src/api/mappers/api/session.ts
+21
-0
shared.ts
cli/web/src/api/mappers/api/shared.ts
+3
-0
index.ts
cli/web/src/api/mappers/api/simulation/index.ts
+1
-0
simulation.ts
cli/web/src/api/mappers/api/simulation/simulation.ts
+13
-0
authentication.ts
cli/web/src/api/mappers/domain/authentication.ts
+24
-0
context.ts
cli/web/src/api/mappers/domain/context.ts
+24
-0
customer.ts
cli/web/src/api/mappers/domain/customer.ts
+28
-0
error.ts
cli/web/src/api/mappers/domain/error.ts
+69
-0
index.ts
cli/web/src/api/mappers/domain/index.ts
+8
-0
session.ts
cli/web/src/api/mappers/domain/session.ts
+19
-0
shared.ts
cli/web/src/api/mappers/domain/shared.ts
+3
-0
context.ts
cli/web/src/api/mappers/domain/simulation/context.ts
+16
-0
index.ts
cli/web/src/api/mappers/domain/simulation/index.ts
+2
-0
simulation.ts
cli/web/src/api/mappers/domain/simulation/simulation.ts
+23
-0
index.ts
cli/web/src/api/mappers/index.ts
+3
-0
authentication.ts
cli/web/src/api/useCases/authentication.ts
+143
-0
context.ts
cli/web/src/api/useCases/context.ts
+58
-0
index.ts
cli/web/src/api/useCases/index.ts
+3
-26
session.ts
cli/web/src/api/useCases/session.ts
+98
-25
shared.ts
cli/web/src/api/useCases/shared.ts
+20
-0
context.ts
cli/web/src/api/useCases/simulation/context.ts
+45
-0
index.ts
cli/web/src/api/useCases/simulation/index.ts
+1
-0
simulation.ts
cli/web/src/api/useCases/simulation/simulation.ts
+50
-0
ButtonWithProgress.tsx
...omponents/atoms/ButtonWithProgress/ButtonWithProgress.tsx
+3
-10
TextFieldWithIcon.tsx
.../components/atoms/TextFieldWithIcon/TextFieldWithIcon.tsx
+2
-6
Drawer.tsx
cli/web/src/components/molecules/Drawer/Drawer.tsx
+2
-2
PopoverVersion.tsx
...rc/components/molecules/PopoverVersion/PopoverVersion.tsx
+16
-19
Address.tsx
cli/web/src/components/templates/Address/Address.tsx
+76
-0
index.ts
cli/web/src/components/templates/Address/index.ts
+3
-0
state.ts
cli/web/src/components/templates/Address/state.ts
+19
-0
styles.ts
cli/web/src/components/templates/Address/styles.ts
+9
-0
FirstAccess.tsx
cli/web/src/components/templates/FirstAccess/FirstAccess.tsx
+56
-0
index.ts
cli/web/src/components/templates/FirstAccess/index.ts
+3
-0
state.ts
cli/web/src/components/templates/FirstAccess/state.ts
+27
-0
styles.ts
cli/web/src/components/templates/FirstAccess/styles.ts
+14
-0
Login.tsx
cli/web/src/components/templates/Login/Login.tsx
+44
-0
index.ts
cli/web/src/components/templates/Login/index.ts
+2
-0
styles.ts
cli/web/src/components/templates/Login/styles.ts
+34
-0
index.ts
cli/web/src/components/templates/index.ts
+3
-0
error.ts
cli/web/src/constants/error.ts
+11
-0
platform.ts
cli/web/src/constants/platform.ts
+13
-0
SessionManager.ts
cli/web/src/curio/SessionManager.ts
+0
-104
index.ts
cli/web/src/curio/index.ts
+0
-104
index.ts
cli/web/src/epics/index.ts
+3
-3
session.ts
cli/web/src/epics/session.ts
+41
-41
system.ts
cli/web/src/epics/system.ts
+20
-20
index.ts
cli/web/src/redux/entities/authentication/index.ts
+14
-0
selectors.ts
cli/web/src/redux/entities/authentication/selectors.ts
+7
-0
shared.ts
cli/web/src/redux/entities/authentication/shared.ts
+20
-0
slice.ts
cli/web/src/redux/entities/authentication/slice.ts
+35
-0
index.ts
cli/web/src/redux/entities/index.ts
+20
-13
shared.ts
cli/web/src/redux/entities/shared.ts
+1
-0
index.ts
cli/web/src/redux/entities/simulation/context/index.ts
+13
-0
selectors.ts
cli/web/src/redux/entities/simulation/context/selectors.ts
+15
-0
slice.ts
cli/web/src/redux/entities/simulation/context/slice.ts
+27
-0
index.ts
cli/web/src/redux/entities/simulation/index.ts
+21
-0
shared.ts
cli/web/src/redux/entities/simulation/shared.ts
+29
-0
index.ts
cli/web/src/redux/entities/simulation/simulation/index.ts
+13
-0
selectors.ts
...web/src/redux/entities/simulation/simulation/selectors.ts
+13
-0
slice.ts
cli/web/src/redux/entities/simulation/simulation/slice.ts
+28
-0
index.ts
cli/web/src/redux/index.ts
+15
-7
middlewares.ts
cli/web/src/redux/middlewares.ts
+51
-11
index.ts
cli/web/src/redux/session/index.ts
+3
-0
reducer.ts
cli/web/src/redux/session/reducer.ts
+18
-31
selectors.ts
cli/web/src/redux/session/selectors.ts
+1
-1
index.ts
cli/web/src/redux/ui/index.ts
+3
-3
index.ts
cli/web/src/redux/ui/login/index.ts
+4
-11
reducer.ts
cli/web/src/redux/ui/login/reducer.ts
+0
-32
selectors.ts
cli/web/src/redux/ui/login/selectors.ts
+1
-1
slice.ts
cli/web/src/redux/ui/login/slice.ts
+74
-0
index.ts
cli/web/src/redux/useCases/authentication/index.ts
+6
-0
selectors.ts
cli/web/src/redux/useCases/authentication/selectors.ts
+4
-0
slice.ts
cli/web/src/redux/useCases/authentication/slice.ts
+109
-0
index.ts
cli/web/src/redux/useCases/index.ts
+25
-0
index.ts
cli/web/src/redux/useCases/simulation/index.ts
+6
-0
selectors.ts
cli/web/src/redux/useCases/simulation/selectors.ts
+3
-0
slice.ts
cli/web/src/redux/useCases/simulation/slice.ts
+57
-0
method.ts
cli/web/src/utils/method.ts
+57
-1
validators.ts
cli/web/src/utils/validators.ts
+5
-0
Login.tsx
cli/web/src/views/Login/Login.tsx
+2
-5
Main.tsx
cli/web/src/views/Main/Main.tsx
+3
-3
connect.ts
cli/web/src/views/Main/connect.ts
+3
-3
CreditLinesList.tsx
...tionCreditLines/pages/CreditLinesList/CreditLinesList.tsx
+116
-86
SliderField.tsx
...mulationCreditLines/pages/CreditLinesList/SliderField.tsx
+15
-17
connect.ts
...ws/SimulationCreditLines/pages/CreditLinesList/connect.ts
+36
-0
CreditLinesInfo.tsx
...ines/pages/Simulation/CreditLinesInfo/CreditLinesInfo.tsx
+34
-15
InstallmentsDialog.tsx
...CreditLinesInfo/InstallmentsDialog/InstallmentsDialog.tsx
+68
-0
index.ts
...es/Simulation/CreditLinesInfo/InstallmentsDialog/index.ts
+2
-0
styles.ts
...s/Simulation/CreditLinesInfo/InstallmentsDialog/styles.ts
+13
-0
connect.ts
...onCreditLines/pages/Simulation/CreditLinesInfo/connect.ts
+20
-0
styles.ts
...ionCreditLines/pages/Simulation/CreditLinesInfo/styles.ts
+2
-1
Simulation.tsx
...ews/SimulationCreditLines/pages/Simulation/Simulation.tsx
+5
-11
CreatePassword.tsx
...rForm/FirstAccessDialog/CreatePassword/CreatePassword.tsx
+31
-0
index.ts
...lation/UserForm/FirstAccessDialog/CreatePassword/index.ts
+2
-0
styles.ts
...ation/UserForm/FirstAccessDialog/CreatePassword/styles.ts
+1
-1
FirstAccessDialog.tsx
...mulation/UserForm/FirstAccessDialog/FirstAccessDialog.tsx
+169
-0
VerifyCPF.tsx
...lation/UserForm/FirstAccessDialog/VerifyCPF/VerifyCPF.tsx
+32
-0
index.ts
.../Simulation/UserForm/FirstAccessDialog/VerifyCPF/index.ts
+2
-0
styles.ts
...Simulation/UserForm/FirstAccessDialog/VerifyCPF/styles.ts
+11
-0
VerifyCode.tsx
...tion/UserForm/FirstAccessDialog/VerifyCode/VerifyCode.tsx
+30
-0
index.ts
...Simulation/UserForm/FirstAccessDialog/VerifyCode/index.ts
+2
-0
styles.ts
...imulation/UserForm/FirstAccessDialog/VerifyCode/styles.ts
+11
-0
connect.ts
...es/pages/Simulation/UserForm/FirstAccessDialog/connect.ts
+46
-0
index.ts
...ines/pages/Simulation/UserForm/FirstAccessDialog/index.ts
+2
-0
styles.ts
...nes/pages/Simulation/UserForm/FirstAccessDialog/styles.ts
+25
-0
UserForm.tsx
...ulationCreditLines/pages/Simulation/UserForm/UserForm.tsx
+52
-32
connect.ts
...imulationCreditLines/pages/Simulation/UserForm/connect.ts
+31
-0
styles.ts
...SimulationCreditLines/pages/Simulation/UserForm/styles.ts
+2
-0
VerificationCode.tsx
...es/pages/Simulation/VerificationCode/VerificationCode.tsx
+0
-45
index.ts
...ionCreditLines/pages/Simulation/VerificationCode/index.ts
+0
-2
router.tsx
cli/web/src/views/SimulationCreditLines/pages/router.tsx
+5
-5
index.tsx
cli/web/src/views/index.tsx
+7
-15
tsconfig.json
cli/web/tsconfig.json
+1
-1
webpack.config.js
cli/web/webpack.config.js
+4
-0
yarn.lock
cli/web/yarn.lock
+5
-0
No files found.
cli/web/.yarnrc
View file @
06b6c363
--registry "https://
registry.npmjs.org/
"
--registry "https://
nexus.dev.evologica.com.br/repository/npm
"
"@curio:registry" "https://nexus.dev.evologica.com.br/repository/npm"
"@curio:registry" "https://nexus.dev.evologica.com.br/repository/npm"
"@dynamo:registry" "https://nexus.dev.evologica.com.br/repository/npm"
"@dynamo:registry" "https://nexus.dev.evologica.com.br/repository/npm"
\ No newline at end of file
cli/web/babel.config.json
View file @
06b6c363
...
@@ -11,14 +11,7 @@
...
@@ -11,14 +11,7 @@
"useBuiltIns"
:
"usage"
,
"useBuiltIns"
:
"usage"
,
"targets"
:
{
"targets"
:
{
"ie"
:
"11"
,
"ie"
:
"11"
,
"browsers"
:
[
"browsers"
:
[
"edge >= 16"
,
"safari >= 9"
,
"firefox >= 57"
,
"ie >= 11"
,
"ios >= 9"
,
"chrome >= 49"
]
"edge >= 16"
,
"safari >= 9"
,
"firefox >= 57"
,
"ie >= 11"
,
"ios >= 9"
,
"chrome >= 49"
]
}
}
}
}
],
],
...
@@ -58,6 +51,7 @@
...
@@ -58,6 +51,7 @@
"@babel/plugin-proposal-class-properties"
,
"@babel/plugin-proposal-class-properties"
,
"@babel/plugin-transform-async-to-generator"
,
"@babel/plugin-transform-async-to-generator"
,
"@babel/plugin-syntax-dynamic-import"
,
"@babel/plugin-syntax-dynamic-import"
,
"@babel/plugin-transform-arrow-functions"
"@babel/plugin-transform-arrow-functions"
,
"@babel/plugin-syntax-top-level-await"
]
]
}
}
cli/web/config/dev.json
View file @
06b6c363
{
{
"service"
:
{
"API_URL"
:
"http://172.16.17.3:8080"
,
"url"
:
"https://srvd1.dev.evologica.com.br/cxClient/cxIsapiClient.dll/gatewayJSON?version=4"
,
"APP_NAME_BROKER"
:
"@microcredito-dev/agente"
,
"server"
:
"192.168.0.34"
,
"APP_NAME_CUSTOMER"
:
"@microcredito-dev/cliente"
,
"system"
:
19
,
"SESSION_KEY_BROKER"
:
"@microcredito-dev/agente"
,
"port"
:
9801
,
"SESSION_KEY_CUSTOMER"
:
"@microcredito-dev/cliente"
"module"
:
1
,
"version"
:
3
},
"accessToken"
:
"ab4dfc4ab84517f900193f8a2530680c73ad3539f75e1f5661bee7065cfcdd32"
,
"resources"
:
{
"get"
:
"https://mdk.dev.evologica.com.br/cxClient/cxIsapiClient.dll/getpr"
,
"put"
:
"https://mdk.dev.evologica.com.br/cxClient/cxIsapiClient.dll/putpr"
},
"logs"
:
true
}
}
cli/web/config/env.json
0 → 100644
View file @
06b6c363
{
"API_URL"
:
"http://192.168.0.34:8080"
,
"APP_NAME_BROKER"
:
"@microcredito-dev/agente"
,
"APP_NAME_CUSTOMER"
:
"@microcredito-dev/cliente"
,
"SESSION_KEY_BROKER"
:
"@microcredito-dev/agente"
,
"SESSION_KEY_CUSTOMER"
:
"@microcredito-dev/cliente"
}
\ No newline at end of file
cli/web/config/prod.json
View file @
06b6c363
{
{
"service"
:
{
"API_URL"
:
"https://microcredito.dev.evologica.com.br"
,
"url"
:
"https://srvd1.dev.evologica.com.br/cxClient/cxIsapiClient.dll/gatewayJSON?version=4"
,
"APP_NAME_BROKER"
:
"@microcredito/agente"
,
"server"
:
"192.168.0.34"
,
"APP_NAME_CUSTOMER"
:
"@microcredito/cliente"
,
"system"
:
19
,
"SESSION_KEY_BROKER"
:
"@microcredito/agente"
,
"port"
:
9801
,
"SESSION_KEY_CUSTOMER"
:
"@microcredito/cliente"
"module"
:
1
,
"version"
:
3
},
"accessToken"
:
"ab4dfc4ab84517f900193f8a2530680c73ad3539f75e1f5661bee7065cfcdd32"
,
"resources"
:
{
"get"
:
"https://mdk.dev.evologica.com.br/cxClient/cxIsapiClient.dll/getpr"
,
"put"
:
"https://mdk.dev.evologica.com.br/cxClient/cxIsapiClient.dll/putpr"
},
"logs"
:
true
}
}
cli/web/config/staging.json
View file @
06b6c363
{
{
"service"
:
{
"API_URL"
:
"https://microcredito.test.evologica.com.br"
,
"url"
:
"https://srvd1.dev.evologica.com.br/cxClient/cxIsapiClient.dll/gatewayJSON?version=4"
,
"APP_NAME_BROKER"
:
"@microcredito-staging/agente"
,
"server"
:
"192.168.0.34"
,
"APP_NAME_CUSTOMER"
:
"@microcredito-staging/cliente"
,
"system"
:
19
,
"SESSION_KEY_BROKER"
:
"@microcredito-staging/agente"
,
"port"
:
9801
,
"SESSION_KEY_CUSTOMER"
:
"@microcredito-staging/cliente"
"module"
:
1
,
"version"
:
3
},
"accessToken"
:
"ab4dfc4ab84517f900193f8a2530680c73ad3539f75e1f5661bee7065cfcdd32"
,
"resources"
:
{
"get"
:
"https://mdk.dev.evologica.com.br/cxClient/cxIsapiClient.dll/getpr"
,
"put"
:
"https://mdk.dev.evologica.com.br/cxClient/cxIsapiClient.dll/putpr"
},
"logs"
:
true
}
}
cli/web/package.json
View file @
06b6c363
...
@@ -90,6 +90,7 @@
...
@@ -90,6 +90,7 @@
"@material-ui/icons"
:
"^4.11.2"
,
"@material-ui/icons"
:
"^4.11.2"
,
"@material-ui/lab"
:
"4.0.0-alpha.58"
,
"@material-ui/lab"
:
"4.0.0-alpha.58"
,
"@material-ui/pickers"
:
"^3.3.10"
,
"@material-ui/pickers"
:
"^3.3.10"
,
"@microcredito/client"
:
"^0.7.11"
,
"@reduxjs/toolkit"
:
"^1.2.5"
,
"@reduxjs/toolkit"
:
"^1.2.5"
,
"@types/react-swipeable-views"
:
"^0.13.1"
,
"@types/react-swipeable-views"
:
"^0.13.1"
,
"@types/react-swipeable-views-utils"
:
"^0.13.3"
,
"@types/react-swipeable-views-utils"
:
"^0.13.3"
,
...
...
cli/web/public/config.json
View file @
06b6c363
{
{
"service"
:
{
"API_URL"
:
"http://172.16.17.3:8080"
,
"url"
:
"https://srvd1.dev.evologica.com.br/cxClient/cxIsapiClient.dll/gatewayJSON?version=4"
,
"APP_NAME_BROKER"
:
"@microcredito-dev/agente"
,
"server"
:
"192.168.0.34"
,
"APP_NAME_CUSTOMER"
:
"@microcredito-dev/cliente"
,
"system"
:
19
,
"SESSION_KEY_BROKER"
:
"@microcredito-dev/agente"
,
"port"
:
9801
,
"SESSION_KEY_CUSTOMER"
:
"@microcredito-dev/cliente"
"module"
:
1
,
"version"
:
3
},
"accessToken"
:
"ab4dfc4ab84517f900193f8a2530680c73ad3539f75e1f5661bee7065cfcdd32"
,
"resources"
:
{
"get"
:
"https://mdk.dev.evologica.com.br/cxClient/cxIsapiClient.dll/getpr"
,
"put"
:
"https://mdk.dev.evologica.com.br/cxClient/cxIsapiClient.dll/putpr"
},
"logs"
:
true
}
}
\ No newline at end of file
cli/web/server.js
View file @
06b6c363
...
@@ -8,6 +8,6 @@ server.get('*', (req, res) => {
...
@@ -8,6 +8,6 @@ server.get('*', (req, res) => {
res
.
sendFile
(
path
.
join
(
__dirname
,
'dist'
,
'index.html'
))
res
.
sendFile
(
path
.
join
(
__dirname
,
'dist'
,
'index.html'
))
})
})
server
.
listen
(
30
1
0
,
()
=>
{
server
.
listen
(
30
0
0
,
()
=>
{
console
.
log
(
'Listening at http://localhost:30
1
0/'
)
console
.
log
(
'Listening at http://localhost:30
0
0/'
)
})
})
cli/web/src/api/domain/authentication/firstAccess.d.ts
0 → 100644
View file @
06b6c363
import
{
Entity
}
from
'@agiliza/utils/method'
import
{
Customer
}
from
'../'
export
interface
City
extends
Entity
{
name
:
string
state
:
string
}
export
interface
State
extends
Entity
{
name
:
string
acronym
:
string
}
export
interface
AuthenticationContext
{
states
:
State
[]
cities
:
City
[]
}
type
OutputGetContext
=
AuthenticationContext
export
interface
GetContext
{
Input
:
void
Output
:
OutputGetContext
}
interface
InputVerifyCPF
{
cpf
:
string
}
export
interface
VerifyCPF
{
Input
:
InputVerifyCPF
Output
:
void
}
interface
InputCreateCustomer
{
cpf
:
string
name
:
string
email
:
string
phone
:
string
cep
:
string
street
:
string
number
:
string
complement
:
string
district
:
string
state
:
string
city
:
string
}
interface
OutputCreateCustomer
{
customer
:
Customer
}
export
interface
CreateCustomer
{
Input
:
InputCreateCustomer
Output
:
OutputCreateCustomer
}
interface
InputSendCode
{
cpf
:
string
email
:
string
}
export
interface
SendCode
{
Input
:
InputSendCode
Output
:
void
}
interface
InputVerifyCode
{
code
:
string
cpf
:
string
}
export
interface
VerifyCode
{
Input
:
InputVerifyCode
Output
:
void
}
interface
InputCreatePassword
{
password
:
string
code
:
string
cpf
:
string
}
export
interface
CreatePassword
{
Input
:
InputCreatePassword
Output
:
void
}
export
interface
GetLoggedCustomer
{
Input
:
void
Output
:
Customer
}
cli/web/src/api/domain/authentication/index.d.ts
0 → 100644
View file @
06b6c363
export
*
from
'./firstAccess'
cli/web/src/api/domain/context.d.ts
0 → 100644
View file @
06b6c363
import
{
Entity
}
from
'@agiliza/utils/method'
export
interface
City
extends
Entity
{
name
:
string
state
:
string
}
export
interface
State
extends
Entity
{
name
:
string
acronym
:
string
}
cli/web/src/api/domain/error.d.ts
0 → 100644
View file @
06b6c363
import
{
ErrorTypes
}
from
'@agiliza/constants/error'
interface
Error
{
type
:
ErrorTypes
omit
?:
boolean
}
// Usuário não está autorizado (Login)
export
interface
UnauthorizedError
extends
Error
{
type
:
ErrorTypes
.
UNAUTHORIZED
message
?:
string
}
// Token de usuário expirou
export
interface
ExpiredSessionError
extends
Error
{
type
:
ErrorTypes
.
EXPIRED_SESSION
message
:
string
}
// Validação de campos (422, resposta padrão para esse status)
export
interface
InvalidFields
{
[
field
:
string
]:
string
}
export
interface
FormValidationError
extends
Error
{
type
:
ErrorTypes
.
FORM_VALIDATION
invalidFields
:
InvalidFields
detail
:
string
}
// Campo ausente do requerido na API (não deve aparecer normalmente)
export
interface
MissingInputError
extends
Error
{
type
:
ErrorTypes
.
MISSING_INPUT
missingFields
:
string
[]
detail
:
string
}
// Erros de servidor (500) e quais outros erros não mapeados
export
interface
InternalServerError
extends
Error
{
type
:
ErrorTypes
.
INTERNAL_SERVER
message
:
string
stack
:
string
}
// Código de Primeiro Acesso/Esqueci a Senha é inválido
export
interface
InvalidVerificationCodeError
extends
Error
{
type
:
ErrorTypes
.
INVALID_EMAIL_CODE
message
:
string
}
// Usuário já existe disponível no sistema (Primeiro Acesso)
export
interface
AlreadyEnabledError
extends
Error
{
type
:
ErrorTypes
.
ALREADY_ENABLED
message
?:
string
}
// Usuário não encontrado (404)
export
interface
UserNotFoundError
extends
Error
{
type
:
ErrorTypes
.
USER_NOT_FOUND
message
?:
string
}
// Usuário não pode agendar uma nova visita
export
interface
ScheduleForbiddenError
extends
Error
{
type
:
ErrorTypes
.
SCHEDULE_FORBIDDEN
message
?:
string
}
export
type
ApiError
=
|
UnauthorizedError
|
ExpiredSessionError
|
FormValidationError
|
InternalServerError
|
MissingInputError
|
InvalidVerificationCodeError
|
AlreadyEnabledError
|
UserNotFoundError
|
ScheduleForbiddenError
cli/web/src/api/domain/index.d.ts
0 → 100644
View file @
06b6c363
export
*
from
'./proposalData'
export
*
from
'./context'
export
*
from
'./error'
export
*
from
'./simulation'
export
*
from
'./authentication'
export
interface
Customer
{
name
:
string
email
:
string
ownerName
?:
string
ownerCPF
?:
string
cpfcnpj
:
string
phone
:
string
avatarUrl
?:
string
address
?:
Partial
<
Address
>
profilePicture
?:
string
}
cli/web/src/api/domain/index.ts
deleted
100644 → 0
View file @
533c4f22
export
*
from
'./proposalData'
cli/web/src/api/domain/proposalData/index.ts
→
cli/web/src/api/domain/proposalData/index.
d.
ts
View file @
06b6c363
File moved
cli/web/src/api/domain/simulation/context.d.ts
0 → 100644
View file @
06b6c363
import
{
Entity
}
from
'@agiliza/utils/method'
export
interface
SimulationCategory
extends
Entity
{
description
:
string
fullDescription
:
string
maxInstallment
:
number
maxGraceMonths
:
number
}
export
interface
SimulationContext
{
gracePeriods
:
CreditGracePeriod
[]
installments
:
CreditInstallment
[]
}
//Prestação
export
interface
CreditInstallment
extends
Entity
{
description
:
string
}
// Carência
export
interface
CreditGracePeriod
extends
Entity
{
description
:
string
}
cli/web/src/api/domain/simulation/index.d.ts
0 → 100644
View file @
06b6c363
export
*
from
'./context'
export
*
from
'./simulation'
cli/web/src/api/domain/simulation/simulation.d.ts
0 → 100644
View file @
06b6c363
import
{
Entity
}
from
'@agiliza/utils/method'
export
interface
SubProduct
extends
Entity
{
description
?:
string
fee
?:
number
IOF
?:
number
maxAmountInstallment
?:
number
installementOptions
:
InstallmentOption
[]
TAC
?:
number
}
export
interface
GetSubProducts
{
Input
:
InputGetSubProducts
Output
:
OutputGetSubProducts
}
interface
InputGetSubProducts
{
creditValue
:
number
idModality
:
string
idGracePeriod
:
string
installmentsNumber
:
number
}
type
OutputGetSubProducts
=
SubProduct
[]
export
interface
InstallmentOption
extends
Entity
{
installmentAmount
?:
number
installmentValue
?:
number
netValue
?:
number
}
cli/web/src/api/dynamo/index.ts
deleted
100644 → 0
View file @
533c4f22
import
{
getSessionManager
}
from
'@agiliza/curio'
import
{
System
as
ApiSystem
}
from
'../interfaces/System'
import
{
DYNAMO_TRANSITIONS
}
from
'../useCases/transitions'
export
interface
SearchParams
{
values
:
Record
<
string
,
any
>
}
export
function
createMenuAPI
()
{
return
{
fetchMenu
:
async
function
()
{
const
sessionManger
=
await
getSessionManager
()
const
response
=
await
sessionManger
.
session
!
.
sendRequest
(
DYNAMO_TRANSITIONS
.
menu
,
{
Level
:
{
_
:
sessionManger
.
session
!
.
module
,
},
Version
:
{
_
:
sessionManger
.
session
!
.
version
,
},
})
return
response
.
System
as
ApiSystem
},
}
}
cli/web/src/api/index.ts
0 → 100644
View file @
06b6c363
interface
JavaConfig
{
API_URL
:
string
APP_NAME_BROKER
:
string
APP_NAME_CUSTOMER
:
string
SESSION_KEY_BROKER
:
string
SESSION_KEY_CUSTOMER
:
string
}
const
JAVA_CONFIG_PATH
=
'./config.json'
let
javaConfig
:
JavaConfig
export
const
getJavaConfig
=
async
()
=>
{
if
(
!
javaConfig
)
{
try
{
javaConfig
=
await
(
await
fetch
(
JAVA_CONFIG_PATH
)).
json
()
return
javaConfig
}
catch
(
e
)
{
if
(
e
instanceof
Response
)
{
//Not found, most likely
throw
process
.
env
.
NODE_ENV
===
'production'
?
'Não foi encontrado o arquivo config.json na raiz da aplicação.'
:
'Arquivo config.json faltando na pasta public.'
}
throw
e
}
}
}
cli/web/src/api/mappers/api/authentication.ts
0 → 100644
View file @
06b6c363
import
{
CreateCustomer
}
from
'@agiliza/api/domain'
import
{
extractNumbers
}
from
'@agiliza/utils/extractors'
import
{
CriarUsuarioPrimeiroAcessoRequest
}
from
'@microcredito/client/dist/apis/ClienteApi'
import
{
ApiAdapter
}
from
'./shared'
export
class
CreateCustomerApiMapper
implements
ApiAdapter
<
CreateCustomer
[
'Input'
],
CriarUsuarioPrimeiroAcessoRequest
>
{
public
mapDomainToApiModel
=
(
input
:
CreateCustomer
[
'Input'
]):
CriarUsuarioPrimeiroAcessoRequest
=>
({
criarUsuarioPrimeiroAcessoRequestApiModel
:
{
usuario
:
{
usuarioCliente
:
{
cpfcnpj
:
extractNumbers
(
input
.
cpf
),
nome
:
input
.
name
,
email
:
input
.
email
,
celular
:
extractNumbers
(
input
.
phone
),
endereco
:
{
cep
:
extractNumbers
(
input
.
cep
),
logradouro
:
input
.
street
,
numero
:
input
.
number
,
estado
:
input
.
state
,
municipio
:
input
.
city
,
complemento
:
input
.
complement
,
bairro
:
input
.
district
,
},
},
},
},
})
}
cli/web/src/api/mappers/api/index.ts
0 → 100644
View file @
06b6c363
import
*
as
AuthenticationApiMappers
from
'./authentication'
import
*
as
SessionApiAdapters
from
'./session'
import
*
as
SimulationApiMappers
from
'./simulation'
export
{
SessionApiAdapters
,
SimulationApiMappers
,
AuthenticationApiMappers
}
cli/web/src/api/mappers/api/session.ts
0 → 100644
View file @
06b6c363
import
{
ClienteApiModels
}
from
'@microcredito/client'
import
{
ApiAdapter
}
from
'./shared'
interface
LoginParams
{
username
:
string
password
:
string
}
export
class
LoginApiAdapter
implements
ApiAdapter
<
LoginParams
,
ClienteApiModels
.
LoginRequest
>
{
public
mapDomainToApiModel
=
(
params
:
LoginParams
):
ClienteApiModels
.
LoginRequest
=>
{
const
result
:
ClienteApiModels
.
LoginRequest
=
{
loginRequestApiModel
:
{
login
:
params
.
username
,
senha
:
params
.
password
,
agente
:
false
,
},
}
return
result
}
}
cli/web/src/api/mappers/api/shared.ts
0 → 100644
View file @
06b6c363
export
interface
ApiAdapter
<
A
,
B
>
{
mapDomainToApiModel
(
domain
:
A
):
B
}
cli/web/src/api/mappers/api/simulation/index.ts
0 → 100644
View file @
06b6c363
export
*
from
'./simulation'
cli/web/src/api/mappers/api/simulation/simulation.ts
0 → 100644
View file @
06b6c363
import
{
GetSubProducts
}
from
'@agiliza/api/domain/simulation/simulation'
import
{
SimularCreditoRequestApiModel
}
from
'@microcredito/client'
import
{
ApiAdapter
}
from
'../shared'
export
class
GetSubProductsApiMapper
implements
ApiAdapter
<
GetSubProducts
[
'Input'
],
SimularCreditoRequestApiModel
>
{
public
mapDomainToApiModel
=
(
input
:
GetSubProducts
[
'Input'
]):
SimularCreditoRequestApiModel
=>
({
valorCredito
:
input
.
creditValue
,
codigoCarencia
:
input
.
idGracePeriod
,
codigoModalidade
:
input
.
idModality
,
numeroParcelas
:
input
.
installmentsNumber
,
})
}
cli/web/src/api/mappers/domain/authentication.ts
0 → 100644
View file @
06b6c363
import
{
EstadoApiModel
,
MunicipioApiModel
}
from
'@microcredito/client'
import
{
City
,
State
}
from
'../../domain'
import
{
DomainAdapter
}
from
'./shared'
export
class
CityMapper
implements
DomainAdapter
<
MunicipioApiModel
,
City
>
{
public
mapApiModelToDomain
=
(
apimodel
:
MunicipioApiModel
):
City
=>
{
return
{
id
:
apimodel
.
codigo
,
name
:
apimodel
.
nome
,
state
:
apimodel
.
estado
,
}
}
}
export
class
StateMapper
implements
DomainAdapter
<
EstadoApiModel
,
State
>
{
public
mapApiModelToDomain
=
(
apimodel
:
EstadoApiModel
):
State
=>
{
return
{
id
:
apimodel
.
codigo
,
name
:
apimodel
.
nome
,
acronym
:
apimodel
.
sigla
,
}
}
}
cli/web/src/api/mappers/domain/context.ts
0 → 100644
View file @
06b6c363
import
{
EstadoApiModel
,
MunicipioApiModel
}
from
'@microcredito/client'
import
{
City
,
State
}
from
'../../domain'
import
{
DomainAdapter
}
from
'./shared'
export
class
CityAdapter
implements
DomainAdapter
<
MunicipioApiModel
,
City
>
{
public
mapApiModelToDomain
=
(
apimodel
:
MunicipioApiModel
):
City
=>
{
return
{
id
:
apimodel
.
codigo
,
name
:
apimodel
.
nome
,
state
:
apimodel
.
estado
,
}
}
}
export
class
StateAdapter
implements
DomainAdapter
<
EstadoApiModel
,
State
>
{
public
mapApiModelToDomain
=
(
apimodel
:
EstadoApiModel
):
State
=>
{
return
{
id
:
apimodel
.
codigo
,
name
:
apimodel
.
nome
,
acronym
:
apimodel
.
sigla
,
}
}
}
cli/web/src/api/mappers/domain/customer.ts
0 → 100644
View file @
06b6c363
import
{
Customer
}
from
'@agiliza/api/domain'
import
{
UsuarioApiModel
}
from
'@microcredito/client'
import
{
DomainAdapter
}
from
'./shared'
export
class
CustomerMapper
implements
DomainAdapter
<
UsuarioApiModel
,
Customer
>
{
public
mapApiModelToDomain
=
({
usuarioCliente
}:
UsuarioApiModel
):
Customer
=>
({
profilePicture
:
usuarioCliente
?.
fotoPerfil
,
cpfcnpj
:
usuarioCliente
?.
cpfcnpj
||
''
,
name
:
usuarioCliente
?.
nome
||
''
,
phone
:
usuarioCliente
?.
celular
||
''
,
ownerCPF
:
usuarioCliente
?.
cpfResponsavel
,
ownerName
:
usuarioCliente
?.
nomeResponsavel
,
address
:
usuarioCliente
?.
endereco
?
{
additionalInfo
:
usuarioCliente
?.
endereco
.
complemento
,
cep
:
usuarioCliente
?.
endereco
.
cep
,
city
:
usuarioCliente
?.
endereco
.
municipio
,
state
:
usuarioCliente
?.
endereco
.
estado
,
district
:
usuarioCliente
?.
endereco
.
bairro
,
number
:
usuarioCliente
?.
endereco
.
numero
,
street
:
usuarioCliente
?.
endereco
.
logradouro
,
id
:
usuarioCliente
?.
endereco
.
id
,
}
:
undefined
,
email
:
usuarioCliente
?.
email
||
''
,
})
}
cli/web/src/api/mappers/domain/error.ts
0 → 100644
View file @
06b6c363
import
{
ApiError
,
InternalServerError
}
from
'@agiliza/api/domain'
import
{
ErrorTypes
}
from
'@agiliza/constants/error'
import
{
DomainAdapter
}
from
'./shared'
/** Default response error adapter */
export
class
ResponseErrorAdapter
implements
DomainAdapter
<
Response
,
Promise
<
ApiError
>>
{
public
async
mapApiModelToDomain
(
error
:
Response
):
Promise
<
ApiError
>
{
let
message
:
string
console
.
log
(
'ERROR'
,
error
)
if
(
error
instanceof
Error
)
{
console
.
log
(
error
)
if
(
error
instanceof
TypeError
&&
error
.
message
.
includes
(
'Network'
))
{
// Network error
message
=
'Ocorreu um problema na conexão ao servidor. Verifique se você está conectado à rede.'
}
else
{
message
=
error
.
message
}
}
else
{
try
{
// console.log('Request:', error)
const
body
=
await
error
.
json
()
console
.
log
(
body
)
if
(
body
.
message
)
{
message
=
body
.
message
}
else
if
(
body
.
erros
)
{
message
=
body
.
erros
[
0
].
motivo
}
else
{
if
(
body
.
error
)
if
(
Array
.
isArray
(
body
.
error
))
message
=
body
.
error
[
0
].
motivo
else
if
(
body
.
status
&&
body
.
status
===
404
)
message
=
`
${
body
.
error
}
\nPath:
${
body
.
path
}
`
else
message
=
body
.
error
else
message
=
body
.
toString
()
}
}
catch
(
e
)
{
// console.log(error)
message
=
error
.
statusText
}
}
return
{
type
:
ErrorTypes
.
INTERNAL_SERVER
,
message
:
message
||
'Ocorreu um problema na requisição ao servidor.'
,
}
as
InternalServerError
}
}
/** Default authenticated response error adapter */
export
class
AuthResponseErrorAdapter
extends
ResponseErrorAdapter
{
public
async
mapApiModelToDomain
(
error
:
Response
):
Promise
<
ApiError
>
{
// if (error instanceof Response && error.status === 403) {
// return {
// type: ErrorTypes.EXPIRED_SESSION,
// message: 'A sua sessão expirou.',
// }
// }
return
super
.
mapApiModelToDomain
(
error
)
}
}
// export class ValidateTokenErrorAdapter extends ResponseErrorAdapter {
// public mapApiModelToDomain = (error: Response): ApiError | undefined => {
// if (error instanceof Response && error.status === 401) {
// return {
// type: ErrorTypes.INVALID_EMAIL_CODE,
// message: 'Código de verificação inválido.',
// }
// }
// }
// }
cli/web/src/api/mappers/domain/index.ts
0 → 100644
View file @
06b6c363
import
*
as
AuthenticationMappers
from
'./authentication'
import
*
as
ContextMappers
from
'./context'
import
*
as
CustomerMappers
from
'./customer'
import
*
as
ErrorMappers
from
'./error'
import
*
as
SessionAdapters
from
'./session'
import
*
as
SimulationMappers
from
'./simulation'
export
{
ContextMappers
,
ErrorMappers
,
SessionAdapters
,
SimulationMappers
,
AuthenticationMappers
,
CustomerMappers
}
cli/web/src/api/mappers/domain/session.ts
0 → 100644
View file @
06b6c363
import
type
{
ApiError
}
from
'@agiliza/api/domain'
import
{
ErrorTypes
}
from
'@agiliza/constants/error'
import
{
ResponseErrorAdapter
}
from
'./error'
export
class
LoginErrorAdapter
extends
ResponseErrorAdapter
{
public
mapApiModelToDomain
=
async
(
error
:
Response
):
Promise
<
ApiError
>
=>
{
if
(
error
instanceof
Response
)
{
if
(
error
.
status
===
403
)
{
// Unauthorized
return
{
type
:
ErrorTypes
.
UNAUTHORIZED
,
message
:
'As credenciais fornecidas não são válidas.'
,
}
}
}
return
super
.
mapApiModelToDomain
(
error
)
}
}
cli/web/src/api/mappers/domain/shared.ts
0 → 100644
View file @
06b6c363
export
interface
DomainAdapter
<
A
,
B
>
{
mapApiModelToDomain
(
apiModel
:
A
):
B
}
cli/web/src/api/mappers/domain/simulation/context.ts
0 → 100644
View file @
06b6c363
import
{
SimulationCategory
}
from
'@agiliza/api/domain'
import
{
CategoriaSimulacaoApiModel
}
from
'@microcredito/client'
import
{
DomainAdapter
}
from
'../shared'
export
class
SimulationCategoryMapper
implements
DomainAdapter
<
CategoriaSimulacaoApiModel
,
SimulationCategory
>
{
public
mapApiModelToDomain
=
(
apimodel
:
CategoriaSimulacaoApiModel
):
SimulationCategory
=>
{
return
{
id
:
apimodel
.
id
||
''
,
description
:
apimodel
.
descricao
||
''
,
fullDescription
:
apimodel
.
descricaoLonga
||
''
,
maxInstallment
:
apimodel
.
numeroMaximoParcelas
,
maxGraceMonths
:
apimodel
.
carenciaMaxima
,
}
}
}
cli/web/src/api/mappers/domain/simulation/index.ts
0 → 100644
View file @
06b6c363
export
*
from
'./context'
export
*
from
'./simulation'
cli/web/src/api/mappers/domain/simulation/simulation.ts
0 → 100644
View file @
06b6c363
import
{
InstallmentOption
,
SubProduct
}
from
'@agiliza/api/domain'
import
{
OpcaoPrestacaoApiModel
,
SubprodutoApiModel
}
from
'@microcredito/client'
import
{
DomainAdapter
}
from
'../shared'
export
class
SubProductMapper
implements
DomainAdapter
<
SubprodutoApiModel
,
SubProduct
>
{
public
mapInstallmentOption
=
(
opcaoPrestacao
:
OpcaoPrestacaoApiModel
):
InstallmentOption
=>
({
id
:
opcaoPrestacao
.
id
||
''
,
installmentAmount
:
opcaoPrestacao
.
quantidadePrestacoes
,
installmentValue
:
opcaoPrestacao
.
valor
,
netValue
:
opcaoPrestacao
.
valorLiquido
,
})
public
mapApiModelToDomain
=
(
subproduto
:
SubprodutoApiModel
):
SubProduct
=>
({
id
:
subproduto
.
id
||
''
,
description
:
subproduto
.
descricao
,
IOF
:
subproduto
.
iof
,
TAC
:
subproduto
.
tac
,
fee
:
subproduto
.
taxa
,
installementOptions
:
subproduto
.
opcoesPrestacao
?.
map
(
this
.
mapInstallmentOption
)
||
[],
maxAmountInstallment
:
subproduto
.
qntMaxPrestacoes
,
})
}
cli/web/src/api/mappers/index.ts
View file @
06b6c363
import
*
as
error
from
'./error'
import
*
as
error
from
'./error'
export
*
from
'./domain'
export
*
from
'./api'
export
{
error
}
export
{
error
}
cli/web/src/api/useCases/authentication.ts
0 → 100644
View file @
06b6c363
import
{
CreateCustomer
,
CreatePassword
,
GetContext
,
GetLoggedCustomer
,
SendCode
,
VerifyCode
,
VerifyCPF
}
from
'@agiliza/api/domain'
import
{
extractNumbers
}
from
'@agiliza/utils/extractors'
import
{
ClienteApi
,
Configuration
,
DominioApi
}
from
'@microcredito/client'
import
{
AuthenticationApiMappers
,
AuthenticationMappers
,
CustomerMappers
,
ErrorMappers
}
from
'../mappers'
import
{
API_URL
,
mapUserAgentToString
,
UserAgent
}
from
'./shared'
export
interface
AuthenticationRepository
{
getContext
():
Promise
<
GetContext
[
'Output'
]
>
verifyCPF
(
input
:
VerifyCPF
[
'Input'
]):
Promise
<
VerifyCPF
[
'Output'
]
>
createCustomer
(
input
:
CreateCustomer
[
'Input'
]):
Promise
<
CreateCustomer
[
'Output'
]
>
sendCode
(
input
:
SendCode
[
'Input'
]):
Promise
<
SendCode
[
'Output'
]
>
verifyCode
(
input
:
VerifyCode
[
'Input'
]):
Promise
<
VerifyCode
[
'Output'
]
>
createPassword
(
input
:
CreatePassword
[
'Input'
]):
Promise
<
CreatePassword
[
'Output'
]
>
getLoggedCustomer
():
Promise
<
GetLoggedCustomer
[
'Output'
]
>
}
export
class
AuthenticationRepositoryImpl
implements
AuthenticationRepository
{
private
api
:
DominioApi
private
clienteApi
:
ClienteApi
private
errorAdapter
:
ErrorMappers
.
ResponseErrorAdapter
private
stateMapper
:
AuthenticationMappers
.
StateMapper
private
cityMapper
:
AuthenticationMappers
.
CityMapper
private
customerMapper
:
CustomerMappers
.
CustomerMapper
private
authenticationApiMapper
:
AuthenticationApiMappers
.
CreateCustomerApiMapper
constructor
(
userAgent
:
string
)
{
this
.
errorAdapter
=
new
ErrorMappers
.
ResponseErrorAdapter
()
this
.
stateMapper
=
new
AuthenticationMappers
.
StateMapper
()
this
.
cityMapper
=
new
AuthenticationMappers
.
CityMapper
()
this
.
customerMapper
=
new
CustomerMappers
.
CustomerMapper
()
this
.
authenticationApiMapper
=
new
AuthenticationApiMappers
.
CreateCustomerApiMapper
()
this
.
api
=
new
DominioApi
(
new
Configuration
({
basePath
:
API_URL
,
headers
:
{
'User-Agent'
:
userAgent
,
},
})
)
this
.
clienteApi
=
new
ClienteApi
(
new
Configuration
({
basePath
:
API_URL
,
headers
:
{
'User-Agent'
:
userAgent
,
},
})
)
}
public
getContext
=
async
():
Promise
<
GetContext
[
'Output'
]
>
=>
{
try
{
const
estados
=
await
this
.
api
.
obterEstados
()
const
cidades
=
await
this
.
api
.
obterMunicipios
()
return
{
states
:
estados
.
map
(
this
.
stateMapper
.
mapApiModelToDomain
),
cities
:
cidades
.
map
(
this
.
cityMapper
.
mapApiModelToDomain
)
}
}
catch
(
e
)
{
const
result
=
await
this
.
errorAdapter
.
mapApiModelToDomain
(
e
)
throw
result
}
}
public
verifyCPF
=
async
(
input
:
VerifyCPF
[
'Input'
]):
Promise
<
VerifyCPF
[
'Output'
]
>
=>
{
try
{
await
this
.
clienteApi
.
iniciarPrimeiroAcessoCliente
({
iniciarPrimeiroAcessoRequestApiModel
:
{
cpfcnpj
:
extractNumbers
(
input
.
cpf
)
}
})
}
catch
(
e
)
{
const
result
=
await
this
.
errorAdapter
.
mapApiModelToDomain
(
e
)
throw
result
}
}
public
createCustomer
=
async
(
input
:
CreateCustomer
[
'Input'
]):
Promise
<
CreateCustomer
[
'Output'
]
>
=>
{
try
{
const
cliente
=
await
this
.
clienteApi
.
criarUsuarioPrimeiroAcesso
(
this
.
authenticationApiMapper
.
mapDomainToApiModel
(
input
))
return
{
customer
:
this
.
customerMapper
.
mapApiModelToDomain
(
cliente
)
}
}
catch
(
e
)
{
const
result
=
await
this
.
errorAdapter
.
mapApiModelToDomain
(
e
)
throw
result
}
}
public
sendCode
=
async
(
input
:
SendCode
[
'Input'
]):
Promise
<
SendCode
[
'Output'
]
>
=>
{
try
{
await
this
.
clienteApi
.
enviarCodigoPrimeiroAcessoCliente
({
enviarCodigoPrimeiroAcessoRequestApiModel
:
{
cpfcnpj
:
extractNumbers
(
input
.
cpf
),
email
:
input
.
email
},
})
}
catch
(
e
)
{
const
result
=
await
this
.
errorAdapter
.
mapApiModelToDomain
(
e
)
throw
result
}
}
public
verifyCode
=
async
(
input
:
VerifyCode
[
'Input'
]):
Promise
<
VerifyCode
[
'Output'
]
>
=>
{
try
{
await
this
.
clienteApi
.
validarCodigoPrimeiroAcessoCliente
({
validarCodigoPrimeiroAcessoRequestApiModel
:
{
cpfcnpj
:
extractNumbers
(
input
.
cpf
),
codigo
:
extractNumbers
(
input
.
code
)
},
})
}
catch
(
e
)
{
const
result
=
await
this
.
errorAdapter
.
mapApiModelToDomain
(
e
)
throw
result
}
}
public
createPassword
=
async
(
input
:
CreatePassword
[
'Input'
]):
Promise
<
CreatePassword
[
'Output'
]
>
=>
{
try
{
await
this
.
clienteApi
.
definirSenhaPrimeiroAcessoCliente
({
definirSenhaPrimeiroAcessoRequestApiModel
:
{
cpfcnpj
:
extractNumbers
(
input
.
cpf
),
codigo
:
extractNumbers
(
input
.
code
),
senha
:
input
.
password
},
})
}
catch
(
e
)
{
const
result
=
await
this
.
errorAdapter
.
mapApiModelToDomain
(
e
)
throw
result
}
}
public
getLoggedCustomer
=
async
():
Promise
<
GetLoggedCustomer
[
'Output'
]
>
=>
{
try
{
const
usuario
=
await
this
.
clienteApi
.
obterUsuarioLogado
()
return
this
.
customerMapper
.
mapApiModelToDomain
(
usuario
)
}
catch
(
e
)
{
const
result
=
await
this
.
errorAdapter
.
mapApiModelToDomain
(
e
)
throw
result
}
}
}
export
class
AuthenticationRepositoryImplFactory
{
static
create
(
userAgent
:
UserAgent
)
{
const
repository
=
new
AuthenticationRepositoryImpl
(
mapUserAgentToString
(
userAgent
))
return
repository
}
}
cli/web/src/api/useCases/context.ts
0 → 100644
View file @
06b6c363
import
{
Configuration
,
DominioApi
}
from
'@microcredito/client'
import
{
City
,
State
}
from
'../domain'
import
{
ContextMappers
,
ErrorMappers
}
from
'../mappers'
import
{
API_URL
,
mapUserAgentToString
,
UserAgent
}
from
'./shared'
export
interface
ContextRepository
{
fetchCities
():
Promise
<
City
[]
>
fetchStates
():
Promise
<
State
[]
>
}
export
class
ContextRepositoryImpl
implements
ContextRepository
{
private
api
:
DominioApi
private
stateAdapter
:
ContextMappers
.
StateAdapter
private
cityAdapter
:
ContextMappers
.
CityAdapter
private
errorAdapter
:
ErrorMappers
.
ResponseErrorAdapter
constructor
(
userAgent
:
string
)
{
this
.
errorAdapter
=
new
ErrorMappers
.
ResponseErrorAdapter
()
this
.
stateAdapter
=
new
ContextMappers
.
StateAdapter
()
this
.
cityAdapter
=
new
ContextMappers
.
CityAdapter
()
this
.
api
=
new
DominioApi
(
new
Configuration
({
basePath
:
API_URL
,
headers
:
{
'User-Agent'
:
userAgent
,
},
})
)
}
public
fetchCities
=
async
():
Promise
<
City
[]
>
=>
{
try
{
const
result
=
await
this
.
api
.
obterMunicipios
()
return
result
.
map
(
this
.
cityAdapter
.
mapApiModelToDomain
)
}
catch
(
e
)
{
const
result
=
await
this
.
errorAdapter
.
mapApiModelToDomain
(
e
)
throw
result
}
}
public
fetchStates
=
async
():
Promise
<
State
[]
>
=>
{
try
{
const
result
=
await
this
.
api
.
obterEstados
()
return
result
.
map
(
this
.
stateAdapter
.
mapApiModelToDomain
)
}
catch
(
e
)
{
const
result
=
await
this
.
errorAdapter
.
mapApiModelToDomain
(
e
)
throw
result
}
}
}
export
class
ContextRepositoryImplFactory
{
static
create
(
userAgent
:
UserAgent
)
{
const
repository
=
new
ContextRepositoryImpl
(
mapUserAgentToString
(
userAgent
))
return
repository
}
}
cli/web/src/api/useCases/index.ts
View file @
06b6c363
import
pMinDelay
from
'p-min-delay'
export
*
from
'./session'
export
*
from
'./simulation'
import
*
as
apiSession
from
'./session'
export
*
from
'./authentication'
type
ApiSessionManager
<
A
>
=
(...
args
:
any
[])
=>
Promise
<
A
|
void
>
interface
ApiMapObject
<
A
>
{
[
key
:
string
]:
ApiSessionManager
<
A
>
}
export
const
applyDelayToApi
=
<
A
,
M
extends
ApiMapObject
<
A
>
|
ApiSessionManager
<
A
>
>
(
apiMapObject
:
M
,
ms
=
600
):
M
=>
Object
.
entries
(
apiMapObject
).
reduce
(
(
acc
,
[
k
,
v
]:
[
string
,
ApiSessionManager
<
any
>
])
=>
({
...
acc
,
[
k
]:
(...
args
:
any
[])
=>
pMinDelay
(
v
(...
args
),
ms
)
}),
{}
as
M
)
export
const
session
=
applyDelayToApi
(
apiSession
)
cli/web/src/api/useCases/session.ts
View file @
06b6c363
import
{
getSessionManager
}
from
'@agiliza/curio'
import
{
extractNumbers
}
from
'@agiliza/utils/extractors'
import
{
ClienteApi
,
Configuration
}
from
'@microcredito/client'
import
{
createMenuAPI
}
from
'../dynamo'
import
{
Customer
}
from
'../domain'
import
{
CustomerMappers
,
SessionAdapters
,
SessionApiAdapters
as
Adapters
}
from
'../mappers'
import
{
API_URL
,
mapUserAgentToString
,
SESSION_KEY
,
UserAgent
}
from
'./shared'
// import { getSessionManager } from '@agiliza/curio'
// import { createMenuAPI } from '../dynamo'
// import { createMenuAPI } from '../dynamo'
//
import { SolicitarRedefinicao, VerificarCodigo, RedefinirSenha } from '../interfaces/Login
'
//
// import { createMenuAPI } from '../dynamo
'
// const ucRecuperarSenha = {
// // import { SolicitarRedefinicao, VerificarCodigo, RedefinirSenha } from '../interfaces/Login'
// id: '3522',
// SOLICITAR_REDEFINICAO: 'RM_SOLICITAR_REDEFINICAO',
// VERIFICAR_CODIGO: 'RM_VERIFICAR_CODIGO',
// DEFIINIR_SENHA: 'RM_DEFINIR_SENHA'
// }
interface
LoginParams
{
// // const ucRecuperarSenha = {
username
:
string
// // id: '3522',
password
:
string
// // SOLICITAR_REDEFINICAO: 'RM_SOLICITAR_REDEFINICAO',
}
// // VERIFICAR_CODIGO: 'RM_VERIFICAR_CODIGO',
// // DEFIINIR_SENHA: 'RM_DEFINIR_SENHA'
// // }
export
const
initialize
=
async
()
=>
{
// interface LoginParams {
await
getSessionManager
()
// username: string
}
// password: string
// }
export
const
login
=
async
({
username
,
password
}:
LoginParams
)
=>
{
// export const initialize = async () => {
const
sessionManager
=
await
getSessionManager
()
// await getSessionManager()
return
sessionManager
.
openMainUseCase
(
username
,
password
)
// }
}
export
const
logout
=
async
()
=>
{
// export const login = async ({ username, password }: LoginParams) => {
const
sessionManager
=
await
getSessionManager
()
// const sessionManager = await getSessionManager()
sessionManager
?.
session
?.
abort
()
// return sessionManager.openMainUseCase(username, password)
}
// }
// export const logout = async () => {
// const sessionManager = await getSessionManager()
// sessionManager?.session?.abort()
// }
export
const
{
fetchMenu
}
=
createMenuAPI
()
//
export const { fetchMenu } = createMenuAPI()
// export const solicitarRedefinicao = async (funcionario: SolicitarRedefinicao) => {
// export const solicitarRedefinicao = async (funcionario: SolicitarRedefinicao) => {
// const mainUseCase = await sessionManager.anonymousConnection()
// const mainUseCase = await sessionManager.anonymousConnection()
...
@@ -72,3 +78,70 @@ export const { fetchMenu } = createMenuAPI()
...
@@ -72,3 +78,70 @@ export const { fetchMenu } = createMenuAPI()
// enviarCodigoSenha,
// enviarCodigoSenha,
// redefinirSenha
// redefinirSenha
// }
// }
export
interface
SessionRepository
{
login
(
username
:
string
,
password
:
string
):
Promise
<
Customer
>
logout
():
void
connect
():
void
}
export
class
SessionRepositoryImpl
implements
SessionRepository
{
private
customer
:
string
private
api
:
ClienteApi
private
loginApiAdapter
:
Adapters
.
LoginApiAdapter
private
errorAdapter
:
SessionAdapters
.
LoginErrorAdapter
private
customerMapper
:
CustomerMappers
.
CustomerMapper
constructor
(
userAgent
:
string
)
{
this
.
customer
=
userAgent
this
.
errorAdapter
=
new
SessionAdapters
.
LoginErrorAdapter
()
this
.
loginApiAdapter
=
new
Adapters
.
LoginApiAdapter
()
this
.
customerMapper
=
new
CustomerMappers
.
CustomerMapper
()
this
.
api
=
new
ClienteApi
(
new
Configuration
({
basePath
:
API_URL
,
headers
:
{
'User-Agent'
:
userAgent
,
},
})
)
}
public
login
=
async
(
username
:
string
,
password
:
string
)
=>
{
try
{
const
params
=
this
.
loginApiAdapter
.
mapDomainToApiModel
({
username
:
extractNumbers
(
username
),
password
})
const
accessToken
=
await
this
.
api
.
login
(
params
)
const
clienteApi
=
new
ClienteApi
(
new
Configuration
({
basePath
:
API_URL
,
accessToken
:
accessToken
.
token
,
headers
:
{
'User-Agent'
:
this
.
customer
,
},
})
)
const
cliente
=
await
clienteApi
.
obterUsuarioLogado
()
return
this
.
customerMapper
.
mapApiModelToDomain
(
cliente
)
}
catch
(
e
)
{
const
result
=
await
this
.
errorAdapter
.
mapApiModelToDomain
(
e
)
throw
result
}
}
public
logout
=
()
=>
{
localStorage
.
removeItem
(
SESSION_KEY
)
}
public
connect
=
()
=>
{
const
sessionKey
=
localStorage
.
getItem
(
SESSION_KEY
)
if
(
sessionKey
)
return
else
throw
new
Error
()
// return await new Promise<void>((res, rej) => {
// })
}
}
export
class
SessionRepositoryImplFactory
{
static
create
(
userAgent
:
UserAgent
)
{
const
repository
=
new
SessionRepositoryImpl
(
mapUserAgentToString
(
userAgent
))
return
repository
}
}
cli/web/src/api/useCases/shared.ts
0 → 100644
View file @
06b6c363
const
config
=
await
fetch
(
'./config.json'
).
then
((
res
)
=>
res
.
json
())
const
{
API_URL
,
APP_NAME_CUSTOMER
,
SESSION_KEY_CUSTOMER
}
=
config
export
{
API_URL
}
export
const
SESSION_KEY
=
SESSION_KEY_CUSTOMER
export
const
APP_NAME
=
APP_NAME_CUSTOMER
export
interface
UserAgent
{
appVersion
:
string
platform
:
{
name
:
string
version
:
string
}
}
export
function
mapUserAgentToString
(
agent
:
UserAgent
)
{
return
`
${
APP_NAME
}
/
${
agent
.
appVersion
}
(
${
agent
.
platform
.
name
}
/
${
agent
.
platform
.
version
}
)`
}
cli/web/src/api/useCases/simulation/context.ts
0 → 100644
View file @
06b6c363
import
{
SimulationCategory
}
from
'@agiliza/api/domain'
import
{
Configuration
,
DominioApi
}
from
'@microcredito/client'
import
{
ErrorMappers
,
SimulationMappers
}
from
'../../mappers'
import
{
API_URL
,
mapUserAgentToString
,
UserAgent
}
from
'../shared'
export
interface
SimulationContextRepository
{
fetchSimulationCategories
():
Promise
<
SimulationCategory
[]
>
}
export
class
SimulationContextRepositoryImpl
implements
SimulationContextRepository
{
private
api
:
DominioApi
private
simulationCategoryMapper
:
SimulationMappers
.
SimulationCategoryMapper
private
errorAdapter
:
ErrorMappers
.
ResponseErrorAdapter
constructor
(
userAgent
:
string
)
{
this
.
errorAdapter
=
new
ErrorMappers
.
ResponseErrorAdapter
()
this
.
simulationCategoryMapper
=
new
SimulationMappers
.
SimulationCategoryMapper
()
this
.
api
=
new
DominioApi
(
new
Configuration
({
basePath
:
API_URL
,
headers
:
{
'User-Agent'
:
userAgent
,
},
})
)
}
public
fetchSimulationCategories
=
async
():
Promise
<
SimulationCategory
[]
>
=>
{
try
{
const
result
=
await
this
.
api
.
obterCategoriasSimulacao
()
return
result
.
map
(
this
.
simulationCategoryMapper
.
mapApiModelToDomain
)
}
catch
(
e
)
{
const
result
=
await
this
.
errorAdapter
.
mapApiModelToDomain
(
e
)
throw
result
}
}
}
export
class
SimulationContextRepositoryImplFactory
{
static
create
(
userAgent
:
UserAgent
)
{
const
repository
=
new
SimulationContextRepositoryImpl
(
mapUserAgentToString
(
userAgent
))
return
repository
}
}
cli/web/src/api/useCases/simulation/index.ts
0 → 100644
View file @
06b6c363
export
*
from
'./context'
cli/web/src/api/useCases/simulation/simulation.ts
0 → 100644
View file @
06b6c363
import
{
GetSubProducts
}
from
'@agiliza/api/domain/simulation/simulation'
import
{
Configuration
}
from
'@microcredito/client'
import
{
AnonimoApi
}
from
'@microcredito/client/dist/apis/AnonimoApi'
import
{
ErrorMappers
,
SimulationApiMappers
,
SimulationMappers
}
from
'../../mappers'
import
{
API_URL
,
mapUserAgentToString
,
UserAgent
}
from
'../shared'
export
interface
SimulationRepository
{
getSubproducts
(
input
:
GetSubProducts
[
'Input'
]):
Promise
<
GetSubProducts
[
'Output'
]
>
}
export
class
SimulationRepositoryImpl
implements
SimulationRepository
{
private
api
:
AnonimoApi
private
getSubproductsApiMapper
:
SimulationApiMappers
.
GetSubProductsApiMapper
private
subproductMapper
:
SimulationMappers
.
SubProductMapper
private
errorAdapter
:
ErrorMappers
.
ResponseErrorAdapter
constructor
(
userAgent
:
string
)
{
this
.
errorAdapter
=
new
ErrorMappers
.
ResponseErrorAdapter
()
this
.
getSubproductsApiMapper
=
new
SimulationApiMappers
.
GetSubProductsApiMapper
()
this
.
subproductMapper
=
new
SimulationMappers
.
SubProductMapper
()
this
.
api
=
new
AnonimoApi
(
new
Configuration
({
basePath
:
API_URL
,
headers
:
{
'User-Agent'
:
userAgent
,
},
})
)
}
public
getSubproducts
=
async
(
input
:
GetSubProducts
[
'Input'
]):
Promise
<
GetSubProducts
[
'Output'
]
>
=>
{
try
{
const
result
=
await
this
.
api
.
anonimoObterSubprodutos
({
simularCreditoRequestApiModel
:
this
.
getSubproductsApiMapper
.
mapDomainToApiModel
(
input
),
})
return
result
.
map
(
this
.
subproductMapper
.
mapApiModelToDomain
)
}
catch
(
e
)
{
const
result
=
await
this
.
errorAdapter
.
mapApiModelToDomain
(
e
)
throw
result
}
}
}
export
class
SimulationRepositoryImplFactory
{
static
create
(
userAgent
:
UserAgent
)
{
const
repository
=
new
SimulationRepositoryImpl
(
mapUserAgentToString
(
userAgent
))
return
repository
}
}
cli/web/src/components/atoms/ButtonWithProgress/ButtonWithProgress.tsx
View file @
06b6c363
...
@@ -7,23 +7,16 @@ import { withStyles, WithStyles } from '@material-ui/core/styles'
...
@@ -7,23 +7,16 @@ import { withStyles, WithStyles } from '@material-ui/core/styles'
import
{
styles
}
from
'./styles'
import
{
styles
}
from
'./styles'
type
ExtendedTypes
=
WithStyles
<
typeof
styles
>
&
type
ExtendedTypes
=
WithStyles
<
typeof
styles
>
&
Pick
<
ButtonProps
,
'disabled'
|
'onClick'
|
'type'
|
'children'
|
'className'
|
'color'
>
Pick
<
ButtonProps
,
'disabled'
|
'onClick'
|
'type'
|
'children'
|
'className'
|
'color'
|
'size'
|
'variant'
>
interface
Props
extends
ExtendedTypes
{
interface
Props
extends
ExtendedTypes
{
fetching
?:
boolean
fetching
?:
boolean
}
}
const
ButtonWithProgress
=
(
props
:
Props
)
=>
{
const
ButtonWithProgress
=
(
props
:
Props
)
=>
{
const
{
className
,
classes
,
fetching
,
disabled
,
onClick
,
type
,
children
,
color
=
'primary'
}
=
props
const
{
className
,
classes
,
fetching
,
disabled
,
onClick
,
type
,
children
,
color
=
'primary'
,
size
,
variant
=
'contained'
}
=
props
return
(
return
(
<
Button
<
Button
className=
{
className
}
disabled=
{
disabled
||
fetching
}
onClick=
{
onClick
}
variant=
{
variant
}
color=
{
color
}
type=
{
type
}
size=
{
size
}
>
className=
{
className
}
disabled=
{
disabled
||
fetching
}
onClick=
{
onClick
}
variant=
"contained"
color=
{
color
}
type=
{
type
}
>
{
fetching
&&
<
LinearProgress
className=
{
classes
.
progress
}
/>
}
{
fetching
&&
<
LinearProgress
className=
{
classes
.
progress
}
/>
}
{
children
}
{
children
}
</
Button
>
</
Button
>
...
...
cli/web/src/components/atoms/TextFieldWithIcon/TextFieldWithIcon.tsx
View file @
06b6c363
...
@@ -9,7 +9,7 @@ import withStyles, { WithStyles } from '@material-ui/styles/withStyles'
...
@@ -9,7 +9,7 @@ import withStyles, { WithStyles } from '@material-ui/styles/withStyles'
import
styles
from
'./styles'
import
styles
from
'./styles'
type
BaseProps
=
WithStyles
<
typeof
styles
>
&
type
BaseProps
=
WithStyles
<
typeof
styles
>
&
Pick
<
TextFieldProps
,
'value'
|
'onChange'
|
'required'
|
'label'
|
'type'
|
'className'
|
'InputProps'
|
'autoFocus'
>
Pick
<
TextFieldProps
,
'value'
|
'onChange'
|
'required'
|
'label'
|
'type'
|
'className'
|
'InputProps'
|
'autoFocus'
|
'inputProps'
>
interface
Props
extends
BaseProps
{}
interface
Props
extends
BaseProps
{}
...
@@ -30,11 +30,7 @@ const TextFieldWithIcon = (props: Props) => {
...
@@ -30,11 +30,7 @@ const TextFieldWithIcon = (props: Props) => {
InputProps
||
{
InputProps
||
{
startAdornment
:
startAdornment
:
type
===
'password'
?
(
type
===
'password'
?
(
<
InputAdornment
<
InputAdornment
position=
"start"
onClick=
{
()
=>
setIsPasswordVisible
(
!
isPasswordVisible
)
}
className=
{
classes
.
inputAdorment
}
>
position=
"start"
onClick=
{
()
=>
setIsPasswordVisible
(
!
isPasswordVisible
)
}
className=
{
classes
.
inputAdorment
}
>
{
isPasswordVisible
?
<
Visibility
/>
:
<
VisibilityOff
/>
}
{
isPasswordVisible
?
<
Visibility
/>
:
<
VisibilityOff
/>
}
</
InputAdornment
>
</
InputAdornment
>
)
:
null
,
)
:
null
,
...
...
cli/web/src/components/molecules/Drawer/Drawer.tsx
View file @
06b6c363
...
@@ -3,7 +3,7 @@ import React from 'react'
...
@@ -3,7 +3,7 @@ import React from 'react'
import
{
RouteComponentProps
}
from
'react-router'
import
{
RouteComponentProps
}
from
'react-router'
import
logo
from
'@agiliza/public/images/logo.svg'
import
logo
from
'@agiliza/public/images/logo.svg'
import
{
actions
as
sessionActions
}
from
'@agiliza/redux/sessio
n'
import
{
actions
as
loginActions
}
from
'@agiliza/redux/ui/logi
n'
import
Divider
from
'@material-ui/core/Divider'
import
Divider
from
'@material-ui/core/Divider'
import
MUIDrawer
from
'@material-ui/core/Drawer'
import
MUIDrawer
from
'@material-ui/core/Drawer'
...
@@ -22,7 +22,7 @@ type BaseProps = RouteComponentProps
...
@@ -22,7 +22,7 @@ type BaseProps = RouteComponentProps
export
interface
Props
extends
BaseProps
{
export
interface
Props
extends
BaseProps
{
drawerOpen
:
boolean
drawerOpen
:
boolean
toggleDrawer
:
()
=>
void
toggleDrawer
:
()
=>
void
logout
:
typeof
sessio
nActions
.
logout
logout
:
typeof
logi
nActions
.
logout
Items
?:
React
.
ComponentType
<
DrawerItemsProps
>
Items
?:
React
.
ComponentType
<
DrawerItemsProps
>
}
}
...
...
cli/web/src/components/molecules/PopoverVersion/PopoverVersion.tsx
View file @
06b6c363
import
React
,
{
use
Effect
,
use
State
}
from
'react'
import
React
,
{
useState
}
from
'react'
import
{
ConfigService
}
from
'@agiliza/curio/SessionManager'
import
Popover
from
'@material-ui/core/Popover'
import
Popover
from
'@material-ui/core/Popover'
import
Typography
from
'@material-ui/core/Typography'
import
Typography
from
'@material-ui/core/Typography'
import
InfoIcon
from
'@material-ui/icons/InfoRounded'
import
InfoIcon
from
'@material-ui/icons/InfoRounded'
...
@@ -8,9 +7,7 @@ import { WithStyles, withStyles } from '@material-ui/styles'
...
@@ -8,9 +7,7 @@ import { WithStyles, withStyles } from '@material-ui/styles'
import
{
styles
}
from
'./styles'
import
{
styles
}
from
'./styles'
interface
Props
extends
WithStyles
<
typeof
styles
>
{
interface
Props
extends
WithStyles
<
typeof
styles
>
{}
service
?:
ConfigService
}
interface
PopItem
{
interface
PopItem
{
key
:
string
key
:
string
...
@@ -19,22 +16,22 @@ interface PopItem {
...
@@ -19,22 +16,22 @@ interface PopItem {
}
}
const
PopoverVersion
=
(
props
:
Props
)
=>
{
const
PopoverVersion
=
(
props
:
Props
)
=>
{
const
{
classes
,
service
}
=
props
const
{
classes
}
=
props
const
[
popItems
,
setPopItems
]
=
useState
<
PopItem
[]
>
([])
const
[
popItems
]
=
useState
<
PopItem
[]
>
([])
const
[
anchor
,
setAnchor
]
=
useState
<
HTMLDivElement
|
null
>
(
null
)
const
[
anchor
,
setAnchor
]
=
useState
<
HTMLDivElement
|
null
>
(
null
)
useEffect
(()
=>
{
//
useEffect(() => {
let
items
:
PopItem
[]
=
[{
key
:
'Versão'
,
value
:
VERSION
}]
//
let items: PopItem[] = [{ key: 'Versão', value: VERSION }]
if
(
service
)
{
//
if (service) {
items
=
items
.
concat
(
//
items = items.concat(
{
key
:
'ISAPI'
,
value
:
service
?.
url
,
underline
:
true
},
//
{ key: 'ISAPI', value: service?.url, underline: true },
{
key
:
'Serviço'
,
value
:
service
?.
server
},
//
{ key: 'Serviço', value: service?.server },
{
key
:
'Porta'
,
value
:
service
?.
port
},
//
{ key: 'Porta', value: service?.port },
{
key
:
'Sistema'
,
value
:
service
?.
system
}
//
{ key: 'Sistema', value: service?.system }
)
//
)
}
//
}
setPopItems
(
items
)
//
setPopItems(items)
},
[
service
])
//
}, [service])
const
createPopItems
=
(
items
:
PopItem
[])
=>
const
createPopItems
=
(
items
:
PopItem
[])
=>
items
.
map
((
item
,
i
)
=>
(
items
.
map
((
item
,
i
)
=>
(
...
...
cli/web/src/components/templates/Address/Address.tsx
0 → 100644
View file @
06b6c363
import
React
,
{
useMemo
}
from
'react'
import
{
City
,
State
}
from
'@agiliza/api/domain'
import
{
ActionType
}
from
'@agiliza/utils/hooks/state'
import
{
maskCEP
}
from
'@agiliza/utils/masks'
import
{
SelectField
,
SelectFieldProps
}
from
'@curio/components'
import
{
TextField
,
TextFieldProps
}
from
'@material-ui/core'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
{
AddressState
as
FormState
}
from
'./state'
import
styles
from
'./styles'
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
interface
Props
extends
ExtendedProps
{
states
:
State
[]
cities
:
City
[]
state
:
FormState
actions
:
ActionType
<
FormState
>
}
const
Address
=
(
props
:
Props
)
=>
{
const
{
classes
,
state
:
_state
,
actions
,
states
,
cities
}
=
props
const
{
cep
,
street
,
number
,
complement
,
state
,
city
,
district
}
=
_state
const
handleChange
=
(
key
:
keyof
FormState
):
TextFieldProps
[
'onChange'
]
=>
(
evt
)
=>
{
actions
.
update
({
[
key
]:
evt
.
target
.
value
})
}
const
handleChangeSelect
=
(
key
:
keyof
FormState
):
SelectFieldProps
[
'onChange'
]
=>
(
value
)
=>
{
actions
.
update
({
[
key
]:
value
})
}
const
availableCities
=
useMemo
(()
=>
{
if
(
state
===
''
)
return
[]
return
cities
.
filter
((
ct
)
=>
ct
.
state
===
state
)
},
[
state
])
return
(
<>
<
TextField
variant=
"outlined"
label=
"CEP"
value=
{
maskCEP
(
cep
)
}
onChange=
{
handleChange
(
'cep'
)
}
inputProps=
{
{
maxLength
:
9
}
}
/>
<
TextField
variant=
"outlined"
label=
"Rua / Avenida"
value=
{
street
}
onChange=
{
handleChange
(
'street'
)
}
/>
<
TextField
variant=
"outlined"
label=
"Número"
value=
{
number
}
onChange=
{
handleChange
(
'number'
)
}
/>
<
TextField
variant=
"outlined"
label=
"Complemento"
value=
{
complement
}
onChange=
{
handleChange
(
'complement'
)
}
/>
<
SelectField
id=
"state-select"
variant=
"outlined"
label=
"Estado"
value=
{
state
}
onChange=
{
handleChangeSelect
(
'state'
)
}
items=
{
states
.
map
((
st
)
=>
({
label
:
st
.
name
,
value
:
st
.
id
}))
}
shrink=
{
false
}
className=
{
classes
.
selectField
}
/>
<
SelectField
id=
"state-select"
variant=
"outlined"
disabled=
{
!
state
}
label=
"Cidade"
value=
{
city
}
onChange=
{
handleChangeSelect
(
'city'
)
}
items=
{
availableCities
.
map
((
st
)
=>
({
label
:
st
.
name
,
value
:
st
.
id
}))
}
shrink=
{
false
}
className=
{
classes
.
selectField
}
/>
<
TextField
variant=
"outlined"
label=
"Bairro"
value=
{
district
}
onChange=
{
handleChange
(
'district'
)
}
/>
</>
)
}
export
default
withStyles
(
styles
)(
Address
)
cli/web/src/components/templates/Address/index.ts
0 → 100644
View file @
06b6c363
export
{
default
}
from
'./Address'
export
*
from
'./Address'
export
*
from
'./state'
cli/web/src/components/templates/Address/state.ts
0 → 100644
View file @
06b6c363
export
interface
AddressState
{
cep
:
string
street
:
string
number
:
string
complement
:
string
district
:
string
state
:
string
city
:
string
}
export
const
initStateAddress
:
AddressState
=
{
cep
:
''
,
street
:
''
,
number
:
''
,
complement
:
''
,
district
:
''
,
state
:
''
,
city
:
''
,
}
cli/web/src/components/templates/Address/styles.ts
0 → 100644
View file @
06b6c363
import
{
Theme
}
from
'@material-ui/core/styles'
import
{
createStyles
}
from
'@material-ui/styles'
// eslint-disable-next-line
export
default
(
theme
:
Theme
)
=>
createStyles
({
form
:
{
display
:
'flex'
,
flexDirection
:
'column'
},
selectField
:
{
marginBottom
:
theme
.
spacing
(
2
)
},
})
cli/web/src/components/templates/FirstAccess/FirstAccess.tsx
0 → 100644
View file @
06b6c363
import
React
from
'react'
import
{
City
,
State
}
from
'@agiliza/api/domain/authentication'
import
{
getErrorProps
,
useErrorValidator
}
from
'@agiliza/utils/hooks/errorValidation'
import
{
ActionType
}
from
'@agiliza/utils/hooks/state'
import
{
maskCPFCNPJ
,
maskPhone
}
from
'@agiliza/utils/masks'
import
{
TextField
,
TextFieldProps
}
from
'@material-ui/core'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
AddressForm
from
'../Address'
import
{
initState
,
State
as
FirstAccessState
}
from
'./state'
import
styles
from
'./styles'
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
interface
Props
extends
ExtendedProps
{
states
:
State
[]
cities
:
City
[]
state
:
FirstAccessState
actions
:
ActionType
<
FirstAccessState
>
}
const
FirstAccess
=
(
props
:
Props
)
=>
{
const
{
classes
,
states
,
cities
,
state
,
actions
}
=
props
const
{
cpf
,
name
,
email
,
phone
,
...
addressState
}
=
state
const
{
errorState
,
actions
:
errorActions
}
=
useErrorValidator
(
initState
)
const
handleChange
=
(
key
:
keyof
FirstAccessState
):
TextFieldProps
[
'onChange'
]
=>
(
evt
)
=>
{
actions
.
update
({
[
key
]:
evt
.
target
.
value
})
errorActions
.
validate
({
[
key
]:
evt
.
target
.
value
})
}
return
(
<
form
className=
{
classes
.
form
}
>
<
TextField
variant=
"outlined"
label=
"CPF"
value=
{
maskCPFCNPJ
(
cpf
)
}
onChange=
{
handleChange
(
'cpf'
)
}
inputProps=
{
{
maxLength
:
14
}
}
disabled
{
...
getErrorProps
(
errorState
.
cpf
)}
/>
<
TextField
variant=
"outlined"
label=
"Nome"
value=
{
name
}
onChange=
{
handleChange
(
'name'
)
}
/>
<
TextField
variant=
"outlined"
label=
"Email"
value=
{
email
}
onChange=
{
handleChange
(
'email'
)
}
/>
<
TextField
variant=
"outlined"
label=
"Telefone"
value=
{
maskPhone
(
phone
)
}
onChange=
{
handleChange
(
'phone'
)
}
inputProps=
{
{
maxLength
:
15
}
}
/>
<
AddressForm
state=
{
addressState
}
actions=
{
actions
}
states=
{
states
}
cities=
{
cities
}
/>
</
form
>
)
}
export
default
withStyles
(
styles
)(
FirstAccess
)
cli/web/src/components/templates/FirstAccess/index.ts
0 → 100644
View file @
06b6c363
export
{
default
}
from
'./FirstAccess'
export
*
from
'./FirstAccess'
export
*
from
'./state'
cli/web/src/components/templates/FirstAccess/state.ts
0 → 100644
View file @
06b6c363
export
interface
State
{
cpf
:
string
name
:
string
email
:
string
phone
:
string
cep
:
string
street
:
string
number
:
string
complement
:
string
district
:
string
state
:
string
city
:
string
}
export
const
initState
:
State
=
{
cpf
:
''
,
email
:
''
,
name
:
''
,
phone
:
''
,
cep
:
''
,
street
:
''
,
number
:
''
,
complement
:
''
,
district
:
''
,
state
:
''
,
city
:
''
,
}
cli/web/src/components/templates/FirstAccess/styles.ts
0 → 100644
View file @
06b6c363
import
{
Theme
}
from
'@material-ui/core/styles'
import
{
createStyles
}
from
'@material-ui/styles'
// eslint-disable-next-line
export
default
(
theme
:
Theme
)
=>
createStyles
({
form
:
{
display
:
'flex'
,
flexDirection
:
'column'
,
'& .MuiTextField-root'
:
{
marginBottom
:
theme
.
spacing
(
2
),
},
},
})
cli/web/src/components/templates/Login/Login.tsx
0 → 100644
View file @
06b6c363
import
React
from
'react'
import
TextFieldWithIcon
from
'@agiliza/components/atoms/TextFieldWithIcon'
import
{
InputAdornment
,
TextFieldProps
}
from
'@material-ui/core'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
{
AccountCircle
}
from
'@material-ui/icons'
import
styles
from
'./styles'
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
interface
Props
extends
ExtendedProps
{
username
:
string
password
:
string
onChange
(
type
:
'username'
|
'password'
):
TextFieldProps
[
'onChange'
]
}
const
Login
=
(
props
:
Props
)
=>
{
const
{
classes
,
username
,
password
,
onChange
}
=
props
return
(
<
form
className=
{
classes
.
form
}
>
<
TextFieldWithIcon
autoFocus
required
value=
{
username
}
onChange=
{
onChange
(
'username'
)
}
label=
"CPF"
className=
{
classes
.
usernameTxtField
}
inputProps=
{
{
maxLength
:
14
}
}
InputProps=
{
{
startAdornment
:
(
<
InputAdornment
position=
"start"
>
<
AccountCircle
/>
</
InputAdornment
>
),
}
}
/>
<
TextFieldWithIcon
required
value=
{
password
}
onChange=
{
onChange
(
'password'
)
}
label=
"Senha"
type=
"password"
/>
</
form
>
)
}
export
default
withStyles
(
styles
)(
Login
)
cli/web/src/components/templates/Login/index.ts
0 → 100644
View file @
06b6c363
export
{
default
}
from
'./Login'
export
*
from
'./Login'
cli/web/src/components/templates/Login/styles.ts
0 → 100644
View file @
06b6c363
import
{
Theme
}
from
'@material-ui/core/styles'
import
{
createStyles
}
from
'@material-ui/styles'
// eslint-disable-next-line
export
default
(
theme
:
Theme
)
=>
createStyles
({
title
:
{
fontSize
:
'150%'
,
fontWeight
:
'bold'
,
overflowWrap
:
'normal'
,
},
formContainer
:
{
height
:
'40%'
,
textAlign
:
'center'
,
justifyContent
:
'space-between'
,
display
:
'flex'
,
flexDirection
:
'column'
,
},
container
:
{
display
:
'flex'
,
height
:
'100vh'
,
flexDirection
:
'column'
,
alignItems
:
'center'
,
justifyContent
:
'center'
,
textAlign
:
'center'
,
},
form
:
{
display
:
'flex'
,
flexDirection
:
'column'
,
width
:
'100%'
,
margin
:
theme
.
spacing
(
2
),
},
usernameTxtField
:
{
marginBottom
:
10
},
})
cli/web/src/components/templates/index.ts
View file @
06b6c363
export
*
from
'./NotFound'
export
*
from
'./NotFound'
export
*
from
'./AccountInputsPhoto'
export
*
from
'./AccountInputsPhoto'
export
*
from
'./Login'
export
*
from
'./Address'
export
*
from
'./FirstAccess'
cli/web/src/constants/error.ts
0 → 100644
View file @
06b6c363
export
enum
ErrorTypes
{
UNAUTHORIZED
,
INTERNAL_SERVER
,
FORM_VALIDATION
,
MISSING_INPUT
,
EXPIRED_SESSION
,
INVALID_EMAIL_CODE
,
ALREADY_ENABLED
,
USER_NOT_FOUND
,
SCHEDULE_FORBIDDEN
,
}
cli/web/src/constants/platform.ts
0 → 100644
View file @
06b6c363
import
{
UserAgent
}
from
'@agiliza/api/useCases/shared'
import
packagejson
from
'../../package.json'
const
{
version
}
=
packagejson
export
const
appPlatform
:
UserAgent
=
{
appVersion
:
version
,
platform
:
{
name
:
'Web'
,
version
:
'1'
,
},
}
cli/web/src/curio/SessionManager.ts
deleted
100644 → 0
View file @
533c4f22
import
{
Dispatch
}
from
'redux'
import
session
from
'@agiliza/redux/session'
import
{
MainUseCase
,
RequestDriver
,
SecurityManager
,
UseCaseMessageType
}
from
'@curio/client'
import
{
ConnectionError
,
DestinataryNotFoundError
}
from
'@curio/client/errors'
import
{
ABORT
}
from
'@curio/client/utils/constants'
const
STORAGE_SESSION_KEY
=
'@agiliza-session-token'
export
interface
ConfigService
{
url
:
string
server
:
string
system
:
number
port
:
number
module
:
number
version
:
number
}
class
Session
extends
MainUseCase
{
module
:
number
|
undefined
version
:
number
|
undefined
constructor
(
token
,
service
,
driver
)
{
super
(
token
,
service
,
driver
)
this
.
module
=
service
.
module
this
.
version
=
service
.
version
}
}
export
class
AnonymousSession
extends
MainUseCase
{}
export
class
SessionManager
extends
SecurityManager
{
public
session
:
Session
|
undefined
private
_dispatch
:
Dispatch
private
_storage
:
Storage
private
_service
:
ConfigService
constructor
(
storage
:
Storage
,
service
:
ConfigService
,
driver
:
RequestDriver
,
dispatch
:
Dispatch
)
{
super
(
service
,
driver
)
this
.
_dispatch
=
dispatch
this
.
_storage
=
storage
this
.
_service
=
service
const
token
=
this
.
_storage
.
getItem
(
STORAGE_SESSION_KEY
)
const
{
actions
}
=
session
if
(
process
.
env
.
NODE_ENV
===
'development'
)
{
dispatch
(
actions
.
setServiceInfo
(
service
))
}
if
(
token
)
{
dispatch
(
actions
.
authRequest
())
this
.
connectMainUseCase
(
new
Session
(
token
,
this
.
service
,
driver
))
this
.
session
!
.
timeoutCheck
()
.
then
(()
=>
dispatch
(
actions
.
authSuccess
()))
.
catch
((
err
)
=>
{})
}
}
public
anonymousConnection
()
{
return
super
.
openMainUseCase
(
'Administrador'
,
''
,
AnonymousSession
)
}
public
async
openMainUseCase
<
U
extends
typeof
MainUseCase
>
(
username
:
string
,
password
:
string
)
{
this
.
session
=
await
super
.
openMainUseCase
(
username
,
password
,
Session
)
this
.
session
.
module
=
this
.
_service
.
module
this
.
session
.
version
=
this
.
_service
.
version
this
.
_storage
.
setItem
(
STORAGE_SESSION_KEY
,
this
.
session
.
token
.
toString
())
this
.
session
.
addListener
(
ABORT
,
()
=>
{
this
.
_unauthenticate
(
false
)
})
this
.
session
.
addListener
(
UseCaseMessageType
.
RESPONSE
,
(
message
:
any
)
=>
{
if
(
message
.
error
instanceof
DestinataryNotFoundError
||
message
.
error
instanceof
ConnectionError
)
{
this
.
_unauthenticate
(
true
)
}
})
return
this
.
session
as
InstanceType
<
U
>
}
public
connectMainUseCase
(
mainUseCase
:
Session
)
{
this
.
session
=
mainUseCase
if
(
!
(
mainUseCase
instanceof
AnonymousSession
))
{
this
.
_storage
.
setItem
(
STORAGE_SESSION_KEY
,
this
.
session
.
token
.
toString
())
}
this
.
session
.
addListener
(
ABORT
,
()
=>
{
this
.
_unauthenticate
(
false
)
})
this
.
session
.
addListener
(
UseCaseMessageType
.
RESPONSE
,
(
message
:
any
)
=>
{
if
(
message
.
error
instanceof
DestinataryNotFoundError
||
message
.
error
instanceof
ConnectionError
)
{
this
.
_unauthenticate
(
true
)
}
})
return
super
.
connectMainUseCase
(
mainUseCase
)
}
private
_unauthenticate
(
expired
:
boolean
)
{
this
.
session
=
undefined
this
.
_storage
.
removeItem
(
STORAGE_SESSION_KEY
)
if
(
expired
)
{
this
.
_dispatch
(
session
.
actions
.
logout
())
}
}
}
cli/web/src/curio/index.ts
deleted
100644 → 0
View file @
533c4f22
import
{
Dispatch
}
from
'redux'
import
{
store
}
from
'@agiliza/redux'
import
{
FetchLink
}
from
'@curio/client/links'
import
{
V3RequestParser
}
from
'@curio/client/parsers'
import
{
createV3Validator
}
from
'@curio/client/validators'
// import config from '../../config/config.json'
import
{
ConfigService
,
SessionManager
}
from
'./SessionManager'
interface
Config
{
service
:
ConfigService
accessToken
:
string
resources
:
{
get
:
string
put
:
string
}
logs
:
boolean
externalApiUrl
:
string
}
const
createSessionManager
=
(
config
:
Config
,
dispatch
:
Dispatch
)
=>
{
const
link
=
new
FetchLink
(
config
.
service
)
const
requestParser
=
new
V3RequestParser
(
config
.
service
)
const
sessionManager
=
new
SessionManager
(
localStorage
,
config
.
service
,
(
request
)
=>
{
return
Promise
.
resolve
(
request
)
.
then
(
requestParser
.
parse
)
.
then
(
JSON
.
stringify
)
.
then
(
link
.
parse
)
.
then
(
link
.
post
)
.
then
((
response
)
=>
response
.
json
())
.
then
(
createV3Validator
(
request
).
validate
)
},
dispatch
)
interface
Attributes
{
[
index
:
string
]:
string
_Id
:
string
_Recipient
:
string
_Sender
:
string
_SerialNumber
:
string
_SignalName
:
string
}
if
(
config
.
logs
)
{
sessionManager
[
Symbol
.
observable
]().
subscribe
({
next
:
(
msg
)
=>
{
if
(
msg
.
signalName
===
'116'
||
msg
.
signalName
===
'120'
||
msg
.
signalName
===
'134'
||
!
Number
(
msg
.
signalName
))
{
const
signalName
=
msg
.
signalName
.
substr
(
msg
.
signalName
.
indexOf
(
'_'
)
+
1
).
replace
(
/_/g
,
' '
)
const
filteredBody
=
Object
.
keys
(
msg
.
body
?
(
msg
.
body
as
Attributes
)
:
{}).
reduce
((
acc
,
curr
)
=>
{
if
(
curr
.
indexOf
(
'_'
)
<
0
)
return
{
...
acc
,
[
curr
]:
(
msg
.
body
as
Attributes
)[
curr
]
}
else
return
acc
},
{})
const
colorType
=
msg
.
type
===
'response'
?
'green'
:
'blue'
console
.
log
(
`%c
${
msg
.
type
.
toUpperCase
()}
%c
${
signalName
}
`
,
`color: white; font-weight: bolder; background:
${
colorType
}
`
,
'font-weight: bolder; font-style: italic;'
,
Object
.
keys
(
filteredBody
).
length
!==
0
?
filteredBody
:
''
)
}
},
error
:
console
.
error
,
complete
:
()
=>
console
.
log
(
'complete'
),
})
}
return
sessionManager
}
const
CONFIG_PATH
=
'./config.json'
let
sm
:
SessionManager
let
config
:
Config
async
function
getSessionManager
()
{
if
(
sm
)
{
return
sm
}
else
{
try
{
const
cnfg
=
await
(
await
fetch
(
CONFIG_PATH
)).
json
()
config
=
cnfg
sm
=
createSessionManager
(
config
,
store
.
dispatch
)
return
sm
}
catch
(
e
)
{
if
(
e
instanceof
Response
)
{
//Not found, most likely
throw
process
.
env
.
NODE_ENV
===
'production'
?
'Não foi encontrado o arquivo config.json na raiz da aplicação.'
:
'Arquivo config.json faltando na pasta public.'
}
throw
e
}
}
}
const
wd
:
any
=
window
wd
.
__CURIO_GET_SESSION__
=
()
=>
getSessionManager
().
then
((
sm
)
=>
sm
.
session
)
export
{
createSessionManager
,
getSessionManager
,
config
}
cli/web/src/epics/index.ts
View file @
06b6c363
import
sessionEpic
from
'./session'
//
import sessionEpic from './session'
import
systemEpic
from
'./system'
//
import systemEpic from './system'
export
{
systemEpic
,
sessionEpic
}
export
{}
cli/web/src/epics/session.ts
View file @
06b6c363
import
{
AnyAction
}
from
'redux'
//
import { AnyAction } from 'redux'
import
{
ActionsObservable
,
combineEpics
,
ofType
}
from
'redux-observable'
//
import { ActionsObservable, combineEpics, ofType } from 'redux-observable'
import
{
from
,
of
}
from
'rxjs'
//
import { from, of } from 'rxjs'
import
{
catchError
,
switchMap
,
tap
}
from
'rxjs/operators'
//
import { catchError, switchMap, tap } from 'rxjs/operators'
import
{
session
}
from
'@agiliza/api/useCases'
//
import { session } from '@agiliza/api/useCases'
import
{
actions
as
sessionActions
,
types
as
sessionTypes
}
from
'@agiliza/redux/session'
//
import { actions as sessionActions, types as sessionTypes } from '@agiliza/redux/session'
import
{
actions
as
loginActions
,
types
as
loginTypes
}
from
'@agiliza/redux/ui/login'
//
import { actions as loginActions, types as loginTypes } from '@agiliza/redux/ui/login'
type
LoginRequestAction
=
ReturnType
<
typeof
loginActions
.
login
>
//
type LoginRequestAction = ReturnType<typeof loginActions.login>
const
loginEpic
=
(
action$
:
ActionsObservable
<
LoginRequestAction
>
)
=>
//
const loginEpic = (action$: ActionsObservable<LoginRequestAction>) =>
action$
.
pipe
(
//
action$.pipe(
ofType
<
AnyAction
,
LoginRequestAction
>
(
loginTypes
.
login
),
//
ofType<AnyAction, LoginRequestAction>(loginTypes.login),
switchMap
((
action
)
=>
//
switchMap((action) =>
from
(
session
.
login
(
action
.
payload
)).
pipe
(
//
from(session.login(action.payload)).pipe(
switchMap
(()
=>
{
//
switchMap(() => {
return
of
(
loginActions
.
loginSuccess
(),
sessionActions
.
authSuccess
())
//
return of(loginActions.loginSuccess(), sessionActions.authSuccess())
}),
//
}),
catchError
((
error
)
=>
of
(
loginActions
.
loginError
(
error
)))
//
catchError((error) => of(loginActions.loginError(error)))
)
//
)
)
//
)
)
//
)
type
LogoutRequestAction
=
ReturnType
<
typeof
sessionActions
.
logout
>
//
type LogoutRequestAction = ReturnType<typeof sessionActions.logout>
const
logoutEpic
=
(
action$
:
ActionsObservable
<
AnyAction
>
)
=>
//
const logoutEpic = (action$: ActionsObservable<AnyAction>) =>
action$
.
pipe
(
//
action$.pipe(
ofType
<
AnyAction
,
LogoutRequestAction
>
(
sessionTypes
.
logout
),
//
ofType<AnyAction, LogoutRequestAction>(sessionTypes.logout),
tap
(()
=>
void
session
.
logout
()),
//
tap(() => void session.logout()),
switchMap
(()
=>
of
(
sessionActions
.
logoutSuccess
(),
{
type
:
'RESET_STORE'
}))
//
switchMap(() => of(sessionActions.logoutSuccess(), { type: 'RESET_STORE' }))
)
//
)
type
InitializeRequestAction
=
ReturnType
<
typeof
sessionActions
.
initialize
>
//
type InitializeRequestAction = ReturnType<typeof sessionActions.initialize>
const
initializeEpic
=
(
action$
:
ActionsObservable
<
InitializeRequestAction
>
)
=>
//
const initializeEpic = (action$: ActionsObservable<InitializeRequestAction>) =>
action$
.
pipe
(
//
action$.pipe(
ofType
<
AnyAction
,
InitializeRequestAction
>
(
sessionTypes
.
initialize
),
//
ofType<AnyAction, InitializeRequestAction>(sessionTypes.initialize),
switchMap
(()
=>
//
switchMap(() =>
from
(
session
.
initialize
()).
pipe
(
//
from(session.initialize()).pipe(
switchMap
(()
=>
{
//
switchMap(() => {
return
of
(
sessionActions
.
initializeSuccess
())
//
return of(sessionActions.initializeSuccess())
}),
//
}),
catchError
((
error
)
=>
of
(
sessionActions
.
initializeError
(
error
)))
//
catchError((error) => of(sessionActions.initializeError(error)))
)
//
)
)
//
)
)
//
)
export
default
combineEpics
(
loginEpic
,
logoutEpic
,
initializeEpic
)
//
export default combineEpics(loginEpic, logoutEpic, initializeEpic)
cli/web/src/epics/system.ts
View file @
06b6c363
import
{
AnyAction
}
from
'redux'
//
import { AnyAction } from 'redux'
import
{
ActionsObservable
,
combineEpics
,
ofType
}
from
'redux-observable'
//
import { ActionsObservable, combineEpics, ofType } from 'redux-observable'
import
{
from
,
of
}
from
'rxjs'
//
import { from, of } from 'rxjs'
import
{
catchError
,
switchMap
}
from
'rxjs/operators'
//
import { catchError, switchMap } from 'rxjs/operators'
import
{
mapSystemApiToStore
}
from
'@agiliza/api/mappers/system'
//
import { mapSystemApiToStore } from '@agiliza/api/mappers/system'
import
{
session
}
from
'@agiliza/api/useCases'
//
import { session } from '@agiliza/api/useCases'
import
{
actions
,
types
}
from
'@agiliza/redux/ui/system'
//
import { actions, types } from '@agiliza/redux/ui/system'
import
{
getError
}
from
'@agiliza/utils/method'
//
import { getError } from '@agiliza/utils/method'
type
FetchMenuAction
=
ReturnType
<
typeof
actions
.
fetchMenu
>
//
type FetchMenuAction = ReturnType<typeof actions.fetchMenu>
const
fetchMenuEpic
=
(
action$
:
ActionsObservable
<
AnyAction
>
)
=>
//
const fetchMenuEpic = (action$: ActionsObservable<AnyAction>) =>
action$
.
pipe
(
//
action$.pipe(
ofType
<
AnyAction
,
FetchMenuAction
>
(
types
.
fetchMenu
),
//
ofType<AnyAction, FetchMenuAction>(types.fetchMenu),
switchMap
(()
=>
//
switchMap(() =>
from
(
session
.
fetchMenu
()).
pipe
(
//
from(session.fetchMenu()).pipe(
switchMap
((
menu
)
=>
of
(
actions
.
fetchMenuSuccess
(
mapSystemApiToStore
(
menu
)))),
//
switchMap((menu) => of(actions.fetchMenuSuccess(mapSystemApiToStore(menu)))),
catchError
((
error
)
=>
of
(
actions
.
fetchMenuError
(
getError
(
error
))))
//
catchError((error) => of(actions.fetchMenuError(getError(error))))
)
//
)
)
//
)
)
//
)
export
default
combineEpics
(
fetchMenuEpic
)
//
export default combineEpics(fetchMenuEpic)
cli/web/src/redux/entities/authentication/index.ts
0 → 100644
View file @
06b6c363
import
{
getActionTypes
}
from
'@agiliza/utils/method'
import
*
as
selectors
from
'./selectors'
import
*
as
shared
from
'./shared'
import
slice
from
'./slice'
export
*
from
'./slice'
const
actions
=
slice
.
actions
const
reducer
=
slice
.
reducer
const
types
=
getActionTypes
(
slice
.
actions
)
export
{
actions
,
types
,
selectors
,
shared
}
export
default
reducer
cli/web/src/redux/entities/authentication/selectors.ts
0 → 100644
View file @
06b6c363
import
{
values
}
from
'@agiliza/utils/method'
import
{
Store
}
from
'./slice'
export
const
getContext
=
(
state
:
Store
)
=>
state
export
const
getContextEntities
=
(
state
:
Store
)
=>
({
states
:
values
(
state
.
states
.
byId
),
cities
:
values
(
state
.
cities
.
byId
)
})
cli/web/src/redux/entities/authentication/shared.ts
0 → 100644
View file @
06b6c363
import
{
normalize
,
schema
}
from
'normalizr'
import
{
City
,
GetContext
,
State
}
from
'@agiliza/api/domain/authentication'
import
{
NormalizedEntity
}
from
'@agiliza/utils/method'
export
interface
NormalizedContext
{
states
:
NormalizedEntity
<
State
>
cities
:
NormalizedEntity
<
City
>
}
const
states
=
new
schema
.
Array
(
new
schema
.
Entity
(
'states'
))
const
cities
=
new
schema
.
Array
(
new
schema
.
Entity
(
'cities'
))
const
contextEntities
=
new
schema
.
Object
({
states
,
cities
})
export
const
normalizeContext
=
(
context
:
GetContext
[
'Output'
])
=>
{
const
{
entities
}
=
normalize
(
context
,
contextEntities
)
const
normalizedEntities
=
entities
as
unknown
as
NormalizedContext
return
normalizedEntities
}
cli/web/src/redux/entities/authentication/slice.ts
0 → 100644
View file @
06b6c363
import
{
City
,
GetContext
,
State
}
from
'@agiliza/api/domain/authentication'
import
{
types
as
fetchTypes
}
from
'@agiliza/redux/useCases/authentication'
import
{
EntityStore
,
keys
}
from
'@agiliza/utils/method'
import
{
createSlice
,
PayloadAction
}
from
'@reduxjs/toolkit'
import
{
PREFIX
}
from
'../shared'
import
{
normalizeContext
}
from
'./shared'
export
interface
Store
{
states
:
EntityStore
<
State
>
cities
:
EntityStore
<
City
>
}
export
const
initialState
:
Store
=
{
states
:
{
byId
:
{},
allIds
:
[]
},
cities
:
{
byId
:
{},
allIds
:
[]
},
}
export
default
createSlice
({
name
:
`
${
PREFIX
}
/authentication`
,
initialState
,
reducers
:
{},
extraReducers
:
{
[
fetchTypes
.
getContext
.
fulfilled
]:
(
state
,
action
:
PayloadAction
<
GetContext
[
'Output'
]
>
)
=>
{
const
normalized
=
normalizeContext
(
action
.
payload
)
console
.
log
(
normalized
)
state
.
states
.
byId
=
normalized
.
states
state
.
states
.
allIds
=
keys
(
normalized
.
states
)
state
.
cities
.
byId
=
normalized
.
cities
state
.
cities
.
allIds
=
keys
(
normalized
.
cities
)
},
},
})
cli/web/src/redux/entities/index.ts
View file @
06b6c363
// import { initialState as profileInitState, reducer as profile, State as Profiles } from './profiles'
import
authentication
,
{
initialState
as
authenticationInitState
,
Store
as
AuthenticationState
}
from
'./authentication'
import
simulation
,
{
initialState
as
simulationInitState
,
State
as
SimulationState
}
from
'./simulation'
import
{
initialState
as
systemInitState
,
reducer
as
system
,
State
as
System
}
from
'./system'
import
{
initialState
as
systemInitState
,
reducer
as
system
,
State
as
System
}
from
'./system'
// import { initialState as userInitState, reducer as user, State as Users } from './users'
export
interface
EntitiesState
{
export
interface
EntitiesState
{
// user: Users
// profile: Profiles
system
:
System
system
:
System
simulation
:
SimulationState
authentication
:
AuthenticationState
}
}
const
reducers
=
{
// user,
// profile,
system
}
export
const
initialState
:
EntitiesState
=
{
export
const
initialState
:
EntitiesState
=
{
// user: userInitState,
simulation
:
simulationInitState
,
// profile: profileInitState,
system
:
systemInitState
,
system
:
systemInitState
authentication
:
authenticationInitState
,
}
const
reducers
=
{
simulation
,
system
,
authentication
,
}
}
export
default
reducers
export
default
reducers
cli/web/src/redux/entities/shared.ts
0 → 100644
View file @
06b6c363
export
const
PREFIX
=
'entities'
cli/web/src/redux/entities/simulation/context/index.ts
0 → 100644
View file @
06b6c363
import
{
getActionTypes
}
from
'@agiliza/utils/method'
import
*
as
selectors
from
'./selectors'
import
slice
from
'./slice'
export
*
from
'./slice'
const
actions
=
slice
.
actions
const
reducer
=
slice
.
reducer
const
types
=
getActionTypes
(
slice
.
actions
)
export
{
actions
,
types
,
selectors
}
export
default
reducer
cli/web/src/redux/entities/simulation/context/selectors.ts
0 → 100644
View file @
06b6c363
import
{
createSelector
}
from
'@reduxjs/toolkit'
import
{
Store
}
from
'./slice'
export
const
getAllIds
=
(
key
:
keyof
Store
)
=>
(
state
:
Store
)
=>
{
return
state
[
key
].
allIds
}
export
const
getById
=
(
key
:
keyof
Store
)
=>
(
state
:
Store
)
=>
{
return
state
[
key
].
byId
}
export
const
getSimulationCategories
=
createSelector
(
getById
(
'simulationCategories'
),
getAllIds
(
'simulationCategories'
),
(
byId
,
allIds
)
=>
allIds
.
map
((
id
)
=>
byId
[
id
])
)
cli/web/src/redux/entities/simulation/context/slice.ts
0 → 100644
View file @
06b6c363
import
{
SimulationCategory
}
from
'@agiliza/api/domain'
import
{
types
as
fetchTypes
}
from
'@agiliza/redux/useCases/simulation'
import
{
EntityStore
,
syncAllIds
,
syncById
}
from
'@agiliza/utils/method'
import
{
createSlice
,
PayloadAction
}
from
'@reduxjs/toolkit'
import
{
normalizeSimulationCategories
,
SIMULATION_PREFIX
}
from
'../shared'
export
interface
Store
{
simulationCategories
:
EntityStore
<
SimulationCategory
>
}
export
const
initialState
:
Store
=
{
simulationCategories
:
{
byId
:
{},
allIds
:
[]
},
}
export
default
createSlice
({
name
:
`
${
SIMULATION_PREFIX
}
/context`
,
initialState
,
reducers
:
{},
extraReducers
:
{
[
fetchTypes
.
fetchSimulationCategories
.
fulfilled
]:
(
state
,
action
:
PayloadAction
<
SimulationCategory
[]
>
)
=>
{
const
normalized
=
normalizeSimulationCategories
(
action
.
payload
)
state
.
simulationCategories
.
byId
=
syncById
(
state
.
simulationCategories
,
normalized
.
simulationCategories
)
state
.
simulationCategories
.
allIds
=
syncAllIds
(
state
.
simulationCategories
,
normalized
.
simulationCategories
)
},
},
})
cli/web/src/redux/entities/simulation/index.ts
0 → 100644
View file @
06b6c363
import
{
combineReducers
}
from
'redux'
import
context
,
{
initialState
as
contextInitState
,
Store
as
ContextStore
}
from
'./context'
import
simulation
,
{
initialState
as
simulationInitState
,
Store
as
SimulationStore
}
from
'./simulation'
export
interface
State
{
context
:
ContextStore
simulation
:
SimulationStore
}
export
const
initialState
:
State
=
{
context
:
contextInitState
,
simulation
:
simulationInitState
,
}
export
default
combineReducers
({
context
,
simulation
,
})
cli/web/src/redux/entities/simulation/shared.ts
0 → 100644
View file @
06b6c363
import
{
normalize
,
schema
}
from
'normalizr'
import
{
SimulationCategory
,
SubProduct
}
from
'@agiliza/api/domain'
import
{
NormalizedEntity
}
from
'@agiliza/utils/method'
export
const
SIMULATION_PREFIX
=
'entities/simulation'
export
interface
NormalizedSimulationCategories
{
simulationCategories
:
NormalizedEntity
<
SimulationCategory
>
}
export
interface
NormalizedSubproducts
{
subproducts
:
NormalizedEntity
<
SubProduct
>
}
const
simulationCategory
=
new
schema
.
Array
(
new
schema
.
Entity
(
'simulationCategories'
))
const
subProduct
=
new
schema
.
Array
(
new
schema
.
Entity
(
'subproducts'
))
export
const
normalizeSimulationCategories
=
(
sCs
:
SimulationCategory
[])
=>
{
const
{
entities
}
=
normalize
(
sCs
,
simulationCategory
)
const
normalizedEntities
=
entities
as
unknown
as
NormalizedSimulationCategories
return
normalizedEntities
}
export
const
normalizeSubproducts
=
(
sPs
:
SubProduct
[])
=>
{
const
{
entities
}
=
normalize
(
sPs
,
subProduct
)
const
normalizedEntities
=
entities
as
unknown
as
NormalizedSubproducts
return
normalizedEntities
}
cli/web/src/redux/entities/simulation/simulation/index.ts
0 → 100644
View file @
06b6c363
import
{
getActionTypes
}
from
'@agiliza/utils/method'
import
*
as
selectors
from
'./selectors'
import
slice
from
'./slice'
export
*
from
'./slice'
const
actions
=
slice
.
actions
const
reducer
=
slice
.
reducer
const
types
=
getActionTypes
(
slice
.
actions
)
export
{
actions
,
types
,
selectors
}
export
default
reducer
cli/web/src/redux/entities/simulation/simulation/selectors.ts
0 → 100644
View file @
06b6c363
import
{
createSelector
}
from
'@reduxjs/toolkit'
import
{
Store
}
from
'./slice'
export
const
getAllIds
=
(
key
:
keyof
Store
)
=>
(
state
:
Store
)
=>
{
return
state
[
key
].
allIds
}
export
const
getById
=
(
key
:
keyof
Store
)
=>
(
state
:
Store
)
=>
{
return
state
[
key
].
byId
}
export
const
getSubproducts
=
createSelector
(
getById
(
'subproducts'
),
getAllIds
(
'subproducts'
),
(
byId
,
allIds
)
=>
allIds
.
map
((
id
)
=>
byId
[
id
]))
cli/web/src/redux/entities/simulation/simulation/slice.ts
0 → 100644
View file @
06b6c363
import
{
GetSubProducts
,
SubProduct
}
from
'@agiliza/api/domain'
import
{
types
as
fetchTypes
}
from
'@agiliza/redux/useCases/simulation'
import
{
EntityStore
,
syncAllIds
,
syncById
}
from
'@agiliza/utils/method'
import
{
createSlice
,
PayloadAction
}
from
'@reduxjs/toolkit'
import
{
normalizeSubproducts
,
SIMULATION_PREFIX
}
from
'../shared'
export
interface
Store
{
subproducts
:
EntityStore
<
SubProduct
>
}
export
const
initialState
:
Store
=
{
subproducts
:
{
byId
:
{},
allIds
:
[]
},
}
export
default
createSlice
({
name
:
`
${
SIMULATION_PREFIX
}
/simulation`
,
initialState
,
reducers
:
{},
extraReducers
:
{
[
fetchTypes
.
getSubproducts
.
fulfilled
]:
(
state
,
action
:
PayloadAction
<
GetSubProducts
[
'Output'
]
>
)
=>
{
const
normalized
=
normalizeSubproducts
(
action
.
payload
)
state
.
subproducts
.
byId
=
syncById
(
state
.
subproducts
,
normalized
.
subproducts
)
state
.
subproducts
.
allIds
=
syncAllIds
(
state
.
subproducts
,
normalized
.
subproducts
)
},
},
})
cli/web/src/redux/index.ts
View file @
06b6c363
import
deepmerge
from
'deepmerge'
import
deepmerge
from
'deepmerge'
import
{
AnyAction
,
combineReducers
,
Middleware
,
Reducer
}
from
'redux'
import
{
AnyAction
,
combineReducers
,
Middleware
,
Reducer
}
from
'redux'
import
{
createLogger
}
from
'redux-logger'
import
{
combineEpics
,
createEpicMiddleware
,
Epic
}
from
'redux-observable'
import
{
combineEpics
,
createEpicMiddleware
,
Epic
}
from
'redux-observable'
import
{
sessionEpic
}
from
'@agiliza/epics'
//
import { sessionEpic } from '@agiliza/epics'
import
{
configureStore
}
from
'@reduxjs/toolkit'
import
{
configureStore
,
getDefaultMiddleware
}
from
'@reduxjs/toolkit'
import
entitiesReducer
,
{
EntitiesState
,
initialState
as
entitiesInitState
}
from
'./entities'
import
entitiesReducer
,
{
EntitiesState
,
initialState
as
entitiesInitState
}
from
'./entities'
import
{
errorMiddleware
}
from
'./middlewares'
import
{
errorMiddleware
,
printMiddleware
}
from
'./middlewares'
import
{
import
{
initialState
as
sessionInitState
,
initialState
as
sessionInitState
,
reducer
as
sessionReducer
,
reducer
as
sessionReducer
,
State
as
SessionState
State
as
SessionState
}
from
'./session'
}
from
'./session'
import
uiReducer
,
{
initialState
as
uiInitState
,
UIState
}
from
'./ui'
import
uiReducer
,
{
initialState
as
uiInitState
,
UIState
}
from
'./ui'
import
useCases
,
{
initialState
as
useCasesInitState
,
UseCasesState
}
from
'./useCases'
type
ReducerMap
=
Record
<
string
,
Reducer
>
type
ReducerMap
=
Record
<
string
,
Reducer
>
type
Reducers
=
Record
<
string
,
Reducer
|
ReducerMap
>
type
Reducers
=
Record
<
string
,
Reducer
|
ReducerMap
>
...
@@ -22,6 +22,7 @@ let registeredReducers: Reducers = {
...
@@ -22,6 +22,7 @@ let registeredReducers: Reducers = {
entities
:
entitiesReducer
,
entities
:
entitiesReducer
,
session
:
sessionReducer
,
session
:
sessionReducer
,
ui
:
uiReducer
,
ui
:
uiReducer
,
useCases
,
}
}
function
recombineReducers
(
reducers
:
Reducers
)
{
function
recombineReducers
(
reducers
:
Reducers
)
{
...
@@ -42,17 +43,23 @@ const rootReducer = (state, action: AnyAction) => {
...
@@ -42,17 +43,23 @@ const rootReducer = (state, action: AnyAction) => {
return
combinedReducers
(
state
,
action
)
return
combinedReducers
(
state
,
action
)
}
}
const
middlewares
=
!
process
.
env
.
PRODUCTION
?
[
createLogger
({
collapsed
:
true
}),
errorMiddleware
]
:
[
errorMiddleware
]
const
defaultMiddleware
=
getDefaultMiddleware
({
serializableCheck
:
false
,
})
const
middlewares
=
!
process
.
env
.
PRODUCTION
?
[
/*createLogger({ collapsed: true }), */
errorMiddleware
,
printMiddleware
]
:
[
errorMiddleware
]
const
epicMiddleware
=
createEpicMiddleware
()
const
epicMiddleware
=
createEpicMiddleware
()
const
store
=
configureStore
({
const
store
=
configureStore
({
reducer
:
rootReducer
,
reducer
:
rootReducer
,
middleware
:
[...
middlewares
,
epicMiddleware
]
as
Middleware
[],
middleware
:
[...
defaultMiddleware
,
...
middlewares
,
epicMiddleware
]
as
Middleware
[],
preloadedState
:
{
preloadedState
:
{
session
:
sessionInitState
,
session
:
sessionInitState
,
ui
:
uiInitState
,
ui
:
uiInitState
,
entities
:
entitiesInitState
,
entities
:
entitiesInitState
,
useCases
:
useCasesInitState
,
},
},
devTools
:
process
.
env
.
NODE_ENV
===
'development'
,
devTools
:
process
.
env
.
NODE_ENV
===
'development'
,
})
})
...
@@ -61,7 +68,7 @@ type EpicMap = Record<string, Epic>
...
@@ -61,7 +68,7 @@ type EpicMap = Record<string, Epic>
type
Epics
=
Record
<
string
,
Epic
|
EpicMap
>
type
Epics
=
Record
<
string
,
Epic
|
EpicMap
>
let
registeredEpics
:
Epics
=
{
let
registeredEpics
:
Epics
=
{
session
:
sessionEpic
,
//
session: sessionEpic,
}
}
function
recombineEpics
(
epics
:
Epics
)
{
function
recombineEpics
(
epics
:
Epics
)
{
...
@@ -98,6 +105,7 @@ export interface StoreState {
...
@@ -98,6 +105,7 @@ export interface StoreState {
ui
:
UIState
ui
:
UIState
session
:
SessionState
session
:
SessionState
entities
:
EntitiesState
entities
:
EntitiesState
useCases
:
UseCasesState
}
}
const
wd
:
any
=
window
const
wd
:
any
=
window
...
...
cli/web/src/redux/middlewares.ts
View file @
06b6c363
import
{
getError
}
from
'@agiliza/utils/method'
import
{
ApiError
}
from
'@agiliza/api/domain'
import
{
Dispatch
,
Middleware
,
PayloadAction
}
from
'@reduxjs/toolkit'
import
{
ErrorTypes
}
from
'@agiliza/constants/error'
import
*
as
ucLogout
from
'@agiliza/redux/ui/login'
import
{
Middleware
,
PayloadAction
,
ThunkDispatch
}
from
'@reduxjs/toolkit'
import
{
actions
as
errorActions
}
from
'./ui/error'
import
{
actions
as
errorActions
}
from
'./ui/error'
export
const
errorMiddleware
:
Middleware
=
// export const errorMiddleware: Middleware =
({
dispatch
})
=>
// ({ dispatch }) =>
(
next
:
Dispatch
<
PayloadAction
<
any
>>
)
=>
// (next: Dispatch<PayloadAction<any>>) =>
((
action
:
PayloadAction
<
any
>
)
=>
{
// ((action: PayloadAction<any>) => {
if
(
/Error$/
.
test
(
action
.
type
)
&&
action
.
payload
)
{
// if (/Error$/.test(action.type) && action.payload) {
const
error
=
getError
(
action
.
payload
)
// const error = getError(action.payload)
dispatch
(
errorActions
.
setErrorMessage
(
error
))
// dispatch(errorActions.setErrorMessage(error))
// }
// return next(action)
// }) as Dispatch<PayloadAction>
export
const
errorMiddleware
:
Middleware
=
(
api
)
=>
(
next
:
ThunkDispatch
<
any
,
any
,
any
>
)
=>
(
action
:
PayloadAction
<
ApiError
>
)
=>
{
if
(
action
.
type
.
includes
(
'/rejected'
))
{
const
error
=
action
.
payload
// console.log(action);
// console.log(error)
// Todo erro de sessão expirada deve imediatamente remover a autenticação do usuário.
if
(
error
.
type
===
ErrorTypes
.
EXPIRED_SESSION
)
{
api
.
dispatch
(
ucLogout
.
actions
.
logout
()
as
any
)
}
else
if
(
!
action
.
type
.
includes
(
'/connect'
)
&&
(
action
.
type
.
includes
(
'useCases'
)
||
action
.
type
.
includes
(
'ui'
)))
{
if
(
error
.
type
!==
ErrorTypes
.
FORM_VALIDATION
&&
error
.
type
!==
ErrorTypes
.
MISSING_INPUT
)
{
api
.
dispatch
(
errorActions
.
setErrorMessage
(
error
.
message
||
'Erro de autenticação'
))
}
}
return
next
(
action
)
}
})
as
Dispatch
<
PayloadAction
>
}
return
next
(
action
)
}
export
const
printMiddleware
:
Middleware
=
(
api
)
=>
(
next
:
ThunkDispatch
<
any
,
any
,
any
>
)
=>
(
action
:
PayloadAction
<
any
,
string
,
{
arg
:
Record
<
string
,
unknown
>
|
string
}
>
)
=>
{
if
(
action
.
type
.
includes
(
'/pending'
))
{
console
.
log
(
`%c
${
action
.
type
.
substring
(
0
,
action
.
type
.
lastIndexOf
(
'/'
))}
%c`
,
`color: white; font-weight: bolder; background: blue`
,
'font-weight: bolder; font-style: italic;'
,
action
.
meta
.
arg
||
''
)
}
if
(
action
.
type
.
includes
(
'/fulfilled'
))
{
console
.
log
(
`%c
${
action
.
type
.
substring
(
0
,
action
.
type
.
lastIndexOf
(
'/'
))}
%c`
,
`color: white; font-weight: bolder; background: green`
,
'font-weight: bolder; font-style: italic;'
,
action
.
payload
?
(
typeof
action
.
payload
===
'object'
?
(
Object
.
keys
(
action
.
payload
).
length
!==
0
?
action
.
payload
:
''
)
:
action
.
payload
)
:
''
)
}
return
next
(
action
)
}
cli/web/src/redux/session/index.ts
View file @
06b6c363
import
{
getTypesActions
}
from
'@agiliza/utils/method'
import
{
getTypesActions
}
from
'@agiliza/utils/method'
import
session
from
'./reducer'
import
session
from
'./reducer'
import
*
as
selectors
from
'./selectors'
export
*
from
'./reducer'
export
*
from
'./reducer'
...
@@ -9,3 +10,5 @@ export const reducer = session.reducer
...
@@ -9,3 +10,5 @@ export const reducer = session.reducer
export
const
types
=
getTypesActions
(
session
.
actions
)
export
const
types
=
getTypesActions
(
session
.
actions
)
export
default
session
export
default
session
export
{
selectors
}
cli/web/src/redux/session/reducer.ts
View file @
06b6c363
import
{
ConfigService
}
from
'@agiliza/curio/SessionManager'
import
{
Customer
}
from
'@agiliza/api/domain'
import
{
types
as
loginTypes
}
from
'@agiliza/redux/ui/login'
import
{
types
as
authenticationTypes
}
from
'@agiliza/redux/useCases/authentication'
import
{
createSlice
,
PayloadAction
}
from
'@reduxjs/toolkit'
import
{
createSlice
,
PayloadAction
}
from
'@reduxjs/toolkit'
export
interface
State
{
export
interface
State
{
...
@@ -6,7 +8,7 @@ export interface State {
...
@@ -6,7 +8,7 @@ export interface State {
authenticating
:
boolean
authenticating
:
boolean
authenticated
:
boolean
authenticated
:
boolean
error
?:
string
error
?:
string
serviceInfo
?:
ConfigService
customer
?:
Customer
}
}
export
const
initialState
:
State
=
{
export
const
initialState
:
State
=
{
...
@@ -15,42 +17,27 @@ export const initialState: State = {
...
@@ -15,42 +17,27 @@ export const initialState: State = {
initializing
:
false
,
initializing
:
false
,
}
}
export
type
Actions
=
'setServiceInfo'
|
'authRequest'
|
'authSuccess'
|
'authError'
|
'logout'
|
'logoutSuccess'
const
session
=
createSlice
({
const
session
=
createSlice
({
name
:
'session'
,
name
:
'session'
,
initialState
,
initialState
,
reducers
:
{
reducers
:
{},
initialize
:
(
state
)
=>
{
extraReducers
:
{
state
.
initializing
=
true
[
loginTypes
.
login
.
fulfilled
]:
(
state
,
action
:
PayloadAction
<
Customer
>
)
=>
{
},
initializeSuccess
:
(
state
)
=>
{
state
.
initializing
=
false
},
initializeError
:
(
state
,
action
:
PayloadAction
<
string
|
undefined
>
)
=>
{
state
.
initializing
=
false
state
.
error
=
action
.
payload
},
authRequest
:
(
state
)
=>
{
state
.
authenticating
=
true
state
.
error
=
undefined
},
authSuccess
:
(
state
)
=>
{
state
.
authenticating
=
false
state
.
authenticated
=
true
state
.
authenticated
=
true
state
.
customer
=
action
.
payload
console
.
log
(
action
.
payload
)
},
},
authError
:
(
state
,
action
:
PayloadAction
<
string
|
undefined
>
)
=>
{
[
loginTypes
.
logout
.
fulfilled
]:
(
state
)
=>
{
state
.
authenticating
=
false
state
.
error
=
action
.
payload
},
logout
:
(
state
)
=>
{
state
.
error
=
undefined
},
logoutSuccess
:
(
state
)
=>
{
state
.
authenticated
=
false
state
.
authenticated
=
false
},
},
setServiceInfo
:
(
state
,
action
:
PayloadAction
<
ConfigService
>
)
=>
{
[
loginTypes
.
connect
.
fulfilled
]:
(
state
)
=>
{
state
.
serviceInfo
=
action
.
payload
state
.
authenticated
=
true
},
// [authenticationTypes.createCustomer.fulfilled]: (state, action: PayloadAction<Customer>) => {
// state.customer = action.payload
// },
[
authenticationTypes
.
getLoggedCustomer
.
fulfilled
]:
(
state
,
action
:
PayloadAction
<
Customer
>
)
=>
{
state
.
customer
=
action
.
payload
},
},
},
},
})
})
...
...
cli/web/src/redux/session/selectors.ts
View file @
06b6c363
...
@@ -4,4 +4,4 @@ export const isAuthenticating = (state: State) => state.authenticating
...
@@ -4,4 +4,4 @@ export const isAuthenticating = (state: State) => state.authenticating
export
const
isAuthenticated
=
(
state
:
State
)
=>
state
.
authenticated
export
const
isAuthenticated
=
(
state
:
State
)
=>
state
.
authenticated
export
const
isInitializing
=
(
state
:
State
)
=>
state
.
initializing
export
const
isInitializing
=
(
state
:
State
)
=>
state
.
initializing
export
const
getError
=
(
state
:
State
)
=>
state
.
error
export
const
getError
=
(
state
:
State
)
=>
state
.
error
export
const
get
ServiceInfo
=
(
state
:
State
)
=>
state
.
serviceInfo
export
const
get
Customer
=
(
state
:
State
)
=>
state
.
customer
cli/web/src/redux/ui/index.ts
View file @
06b6c363
...
@@ -4,7 +4,7 @@ import {
...
@@ -4,7 +4,7 @@ import {
State
as
DrawerState
State
as
DrawerState
}
from
'./drawer'
}
from
'./drawer'
import
{
initialState
as
errorInitialState
,
reducer
as
error
,
State
as
ErrorState
}
from
'./error'
import
{
initialState
as
errorInitialState
,
reducer
as
error
,
State
as
ErrorState
}
from
'./error'
import
{
initialState
as
loginInitialState
,
reducer
as
login
,
State
as
LoginState
}
from
'./login'
import
login
,
{
initialState
as
loginInitialState
,
State
as
LoginState
}
from
'./login'
// import {
// import {
// initialState as profileInitialState,
// initialState as profileInitialState,
// reducer as profile,
// reducer as profile,
...
@@ -35,7 +35,7 @@ const reducers = {
...
@@ -35,7 +35,7 @@ const reducers = {
drawer
,
drawer
,
// user,
// user,
// profile,
// profile,
system
system
,
}
}
export
const
initialState
:
UIState
=
{
export
const
initialState
:
UIState
=
{
...
@@ -44,7 +44,7 @@ export const initialState: UIState = {
...
@@ -44,7 +44,7 @@ export const initialState: UIState = {
drawer
:
drawerInitialState
,
drawer
:
drawerInitialState
,
// user: userInitialState,
// user: userInitialState,
// profile: profileInitialState,
// profile: profileInitialState,
system
:
systemInitialState
system
:
systemInitialState
,
}
}
export
default
reducers
export
default
reducers
cli/web/src/redux/ui/login/index.ts
View file @
06b6c363
import
{
getTypesActions
}
from
'@agiliza/utils/method'
import
login
from
'./reducer'
import
*
as
selectors
from
'./selectors'
import
*
as
selectors
from
'./selectors'
import
slice
from
'./slice'
export
*
from
'./reducer'
export
*
from
'./slice'
const
actions
=
login
.
actions
export
{
selectors
}
const
reducer
=
login
.
reducer
export
default
slice
.
reducer
const
types
=
getTypesActions
(
login
.
actions
)
export
{
actions
,
reducer
,
types
,
selectors
}
export
default
login
cli/web/src/redux/ui/login/reducer.ts
deleted
100644 → 0
View file @
533c4f22
import
{
createSlice
,
PayloadAction
}
from
'@reduxjs/toolkit'
export
interface
State
{
fetching
:
boolean
}
export
const
initialState
:
State
=
{
fetching
:
false
,
}
interface
Login
{
username
:
string
password
:
string
}
const
login
=
createSlice
({
name
:
'ui/login'
,
initialState
,
reducers
:
{
login
(
state
,
action
:
PayloadAction
<
Login
>
)
{
state
.
fetching
=
true
},
loginSuccess
(
state
)
{
state
.
fetching
=
false
},
loginError
(
state
,
action
:
PayloadAction
<
string
>
)
{
state
.
fetching
=
false
},
},
})
export
default
login
cli/web/src/redux/ui/login/selectors.ts
View file @
06b6c363
import
{
State
}
from
'./
reducer
'
import
{
State
}
from
'./
slice
'
export
const
isFetching
=
(
state
:
State
)
=>
state
.
fetching
export
const
isFetching
=
(
state
:
State
)
=>
state
.
fetching
cli/web/src/redux/ui/login/slice.ts
0 → 100644
View file @
06b6c363
import
{
SessionRepositoryImplFactory
}
from
'@agiliza/api/useCases/session'
import
{
appPlatform
}
from
'@agiliza/constants/platform'
import
{
createAsyncReducers
,
getTypesThunkActions
,
values
,
WithSuccess
}
from
'@agiliza/utils/method'
import
{
createAsyncThunk
,
createSlice
,
PayloadAction
}
from
'@reduxjs/toolkit'
const
prefix
=
'ui/login'
export
interface
State
{
fetching
:
boolean
}
export
const
initialState
:
State
=
{
fetching
:
false
,
}
interface
Login
{
username
:
string
password
:
string
}
export
const
actions
=
{
login
:
createAsyncThunk
(
`
${
prefix
}
/login`
,
async
(
args
:
WithSuccess
<
{
username
:
string
;
password
:
string
}
>
,
thunkApi
)
=>
{
const
useCase
=
SessionRepositoryImplFactory
.
create
(
appPlatform
)
try
{
const
{
username
,
password
,
onSuccess
}
=
args
const
customer
=
await
useCase
.
login
(
username
,
password
)
onSuccess
&&
onSuccess
()
return
customer
}
catch
(
e
)
{
return
thunkApi
.
rejectWithValue
(
e
)
}
}),
logout
:
createAsyncThunk
(
`
${
prefix
}
/logout`
,
(
_
,
thunkApi
)
=>
{
const
useCase
=
SessionRepositoryImplFactory
.
create
(
appPlatform
)
useCase
.
logout
()
thunkApi
.
dispatch
({
type
:
'RESET_STORE'
})
return
}),
connect
:
createAsyncThunk
(
`
${
prefix
}
/connect`
,
(
_
,
thunkApi
)
=>
{
const
useCase
=
SessionRepositoryImplFactory
.
create
(
appPlatform
)
try
{
useCase
.
connect
()
}
catch
(
e
)
{
return
thunkApi
.
rejectWithValue
(
e
)
}
}),
}
as
const
export
const
types
=
getTypesThunkActions
(
actions
)
const
login
=
createSlice
({
name
:
prefix
,
initialState
,
reducers
:
{
login
(
state
,
action
:
PayloadAction
<
Login
>
)
{
state
.
fetching
=
true
},
loginSuccess
(
state
)
{
state
.
fetching
=
false
},
loginError
(
state
,
action
:
PayloadAction
<
string
>
)
{
state
.
fetching
=
false
},
},
extraReducers
:
{
...
values
(
types
).
reduce
((
reducers
,
type
)
=>
({
...
reducers
,
...
createAsyncReducers
(
type
)
}),
{}),
},
})
export
default
login
cli/web/src/redux/useCases/authentication/index.ts
0 → 100644
View file @
06b6c363
import
*
as
selectors
from
'./selectors'
import
slice
from
'./slice'
export
*
from
'./slice'
export
{
selectors
}
export
default
slice
.
reducer
cli/web/src/redux/useCases/authentication/selectors.ts
0 → 100644
View file @
06b6c363
import
{
State
}
from
'./slice'
export
const
isFetching
=
(
state
:
State
)
=>
state
.
fetching
export
const
isSendingCode
=
(
state
:
State
)
=>
state
.
sendingCode
cli/web/src/redux/useCases/authentication/slice.ts
0 → 100644
View file @
06b6c363
import
{
CreateCustomer
,
CreatePassword
,
GetLoggedCustomer
,
SendCode
,
VerifyCode
,
VerifyCPF
}
from
'@agiliza/api/domain'
import
{
AuthenticationRepositoryImplFactory
}
from
'@agiliza/api/useCases'
import
{
appPlatform
}
from
'@agiliza/constants/platform'
import
{
createAsyncReducers
,
getTypesThunkActions
,
values
,
WithSuccess
}
from
'@agiliza/utils/method'
import
{
createAsyncThunk
,
createSlice
}
from
'@reduxjs/toolkit'
const
prefix
=
'useCases/authentication'
export
interface
State
{
fetching
:
boolean
sendingCode
:
boolean
}
export
const
initialState
:
State
=
{
fetching
:
false
,
sendingCode
:
false
,
}
export
const
actions
=
{
getContext
:
createAsyncThunk
(
`
${
prefix
}
/getContext`
,
async
(
_
,
thunkApi
)
=>
{
const
useCase
=
AuthenticationRepositoryImplFactory
.
create
(
appPlatform
)
try
{
return
await
useCase
.
getContext
()
}
catch
(
e
)
{
return
thunkApi
.
rejectWithValue
(
e
)
}
}),
verifyCPF
:
createAsyncThunk
(
`
${
prefix
}
/verifyCPF`
,
async
(
input
:
WithSuccess
<
VerifyCPF
[
'Input'
]
>
,
thunkApi
)
=>
{
const
useCase
=
AuthenticationRepositoryImplFactory
.
create
(
appPlatform
)
try
{
await
useCase
.
verifyCPF
(
input
)
input
.
onSuccess
&&
input
.
onSuccess
()
}
catch
(
e
)
{
return
thunkApi
.
rejectWithValue
(
e
)
}
}),
createCustomer
:
createAsyncThunk
(
`
${
prefix
}
/createCustomer`
,
async
(
input
:
WithSuccess
<
CreateCustomer
[
'Input'
]
>
,
thunkApi
)
=>
{
const
useCase
=
AuthenticationRepositoryImplFactory
.
create
(
appPlatform
)
try
{
const
customer
=
await
useCase
.
createCustomer
(
input
)
input
.
onSuccess
&&
input
.
onSuccess
()
return
customer
}
catch
(
e
)
{
return
thunkApi
.
rejectWithValue
(
e
)
}
}),
sendCode
:
createAsyncThunk
(
`
${
prefix
}
/sendCode`
,
async
(
input
:
WithSuccess
<
SendCode
[
'Input'
]
>
,
thunkApi
)
=>
{
const
useCase
=
AuthenticationRepositoryImplFactory
.
create
(
appPlatform
)
try
{
await
useCase
.
sendCode
(
input
)
input
.
onSuccess
&&
input
.
onSuccess
()
}
catch
(
e
)
{
return
thunkApi
.
rejectWithValue
(
e
)
}
}),
verifyCode
:
createAsyncThunk
(
`
${
prefix
}
/verifyCode`
,
async
(
input
:
WithSuccess
<
VerifyCode
[
'Input'
]
>
,
thunkApi
)
=>
{
const
useCase
=
AuthenticationRepositoryImplFactory
.
create
(
appPlatform
)
try
{
await
useCase
.
verifyCode
(
input
)
input
.
onSuccess
&&
input
.
onSuccess
()
}
catch
(
e
)
{
return
thunkApi
.
rejectWithValue
(
e
)
}
}),
createPassword
:
createAsyncThunk
(
`
${
prefix
}
/createPassword`
,
async
(
input
:
WithSuccess
<
CreatePassword
[
'Input'
]
>
,
thunkApi
)
=>
{
const
useCase
=
AuthenticationRepositoryImplFactory
.
create
(
appPlatform
)
try
{
await
useCase
.
createPassword
(
input
)
input
.
onSuccess
&&
input
.
onSuccess
()
}
catch
(
e
)
{
return
thunkApi
.
rejectWithValue
(
e
)
}
}),
getLoggedCustomer
:
createAsyncThunk
(
`
${
prefix
}
/getLoggedCustomer`
,
async
(
input
:
WithSuccess
<
GetLoggedCustomer
[
'Input'
]
>
,
thunkApi
)
=>
{
const
useCase
=
AuthenticationRepositoryImplFactory
.
create
(
appPlatform
)
try
{
const
customer
=
await
useCase
.
getLoggedCustomer
()
input
.
onSuccess
&&
input
.
onSuccess
()
return
customer
}
catch
(
e
)
{
return
thunkApi
.
rejectWithValue
(
e
)
}
}),
}
as
const
export
const
types
=
getTypesThunkActions
(
actions
)
const
slice
=
createSlice
({
name
:
prefix
,
initialState
,
reducers
:
{},
extraReducers
:
{
...
values
(
types
).
reduce
((
reducers
,
type
)
=>
({
...
reducers
,
...
createAsyncReducers
(
type
)
}),
{}),
...
createAsyncReducers
(
types
.
sendCode
,
'sendingCode'
),
},
})
export
default
slice
cli/web/src/redux/useCases/index.ts
0 → 100644
View file @
06b6c363
import
authentication
,
{
initialState
as
authenticationInitialState
,
State
as
AuthenticationState
}
from
'./authentication'
import
simulation
,
{
initialState
as
simulationInitialState
,
State
as
SimulationState
}
from
'./simulation'
export
interface
UseCasesState
{
simulation
:
SimulationState
authentication
:
AuthenticationState
}
const
reducers
=
{
simulation
,
authentication
,
}
export
const
initialState
:
UseCasesState
=
{
simulation
:
simulationInitialState
,
authentication
:
authenticationInitialState
,
}
export
default
reducers
cli/web/src/redux/useCases/simulation/index.ts
0 → 100644
View file @
06b6c363
import
*
as
selectors
from
'./selectors'
import
slice
from
'./slice'
export
*
from
'./slice'
export
{
selectors
}
export
default
slice
.
reducer
cli/web/src/redux/useCases/simulation/selectors.ts
0 → 100644
View file @
06b6c363
import
{
State
}
from
'./slice'
export
const
isFetching
=
(
state
:
State
)
=>
state
.
fetching
cli/web/src/redux/useCases/simulation/slice.ts
0 → 100644
View file @
06b6c363
import
{
GetSubProducts
}
from
'@agiliza/api/domain'
import
{
SimulationContextRepositoryImplFactory
}
from
'@agiliza/api/useCases'
import
{
SimulationRepositoryImplFactory
}
from
'@agiliza/api/useCases/simulation/simulation'
import
{
appPlatform
}
from
'@agiliza/constants/platform'
import
{
createAsyncReducers
,
getTypesThunkActions
,
values
,
WithSuccess
}
from
'@agiliza/utils/method'
import
{
createAsyncThunk
,
createSlice
}
from
'@reduxjs/toolkit'
const
prefix
=
'useCases/simulation'
export
interface
State
{
fetching
:
boolean
}
export
const
initialState
:
State
=
{
fetching
:
false
,
}
export
const
actions
=
{
fetchSimulationCategories
:
createAsyncThunk
(
`
${
prefix
}
/fetchSimulationCategories`
,
async
(
_
,
thunkApi
)
=>
{
const
useCase
=
SimulationContextRepositoryImplFactory
.
create
(
appPlatform
)
try
{
return
await
useCase
.
fetchSimulationCategories
()
}
catch
(
e
)
{
return
thunkApi
.
rejectWithValue
(
e
)
}
}),
getSubproducts
:
createAsyncThunk
(
`
${
prefix
}
/getSubproducts`
,
async
(
input
:
WithSuccess
<
GetSubProducts
[
'Input'
],
GetSubProducts
[
'Output'
]
>
,
thunkApi
)
=>
{
const
useCase
=
SimulationRepositoryImplFactory
.
create
(
appPlatform
)
try
{
const
response
=
await
useCase
.
getSubproducts
(
input
)
input
.
onSuccess
&&
input
.
onSuccess
(
response
)
return
response
}
catch
(
e
)
{
return
thunkApi
.
rejectWithValue
(
e
)
}
}
),
}
as
const
export
const
types
=
getTypesThunkActions
(
actions
)
const
login
=
createSlice
({
name
:
prefix
,
initialState
,
reducers
:
{},
extraReducers
:
{
...
values
(
types
).
reduce
((
reducers
,
type
)
=>
({
...
reducers
,
...
createAsyncReducers
(
type
)
}),
{}),
},
})
export
default
login
cli/web/src/utils/method.ts
View file @
06b6c363
import
deepmerge
from
'deepmerge'
import
deepmerge
from
'deepmerge'
import
{
PayloadAction
}
from
'@reduxjs/toolkit'
import
{
createAsyncThunk
,
PayloadAction
}
from
'@reduxjs/toolkit'
export
const
values
=
(
obj
:
Record
<
string
,
any
>
)
=>
{
export
const
values
=
(
obj
:
Record
<
string
,
any
>
)
=>
{
return
Object
.
values
(
obj
||
{})
return
Object
.
values
(
obj
||
{})
...
@@ -129,3 +129,59 @@ type FirstParameter<T extends (...args: any) => any> = Parameters<T>[0]
...
@@ -129,3 +129,59 @@ type FirstParameter<T extends (...args: any) => any> = Parameters<T>[0]
type
RequiredBy
<
T
,
K
extends
keyof
T
>
=
Pick
<
T
,
K
>
&
Partial
<
Omit
<
T
,
K
>>
type
RequiredBy
<
T
,
K
extends
keyof
T
>
=
Pick
<
T
,
K
>
&
Partial
<
Omit
<
T
,
K
>>
export
type
{
ActionType
,
FirstParameter
,
RequiredBy
}
export
type
{
ActionType
,
FirstParameter
,
RequiredBy
}
interface
AsyncReducers
{
pending
:
string
fulfilled
:
string
rejected
:
string
}
export
const
createAsyncReducers
=
<
Types
extends
AsyncReducers
,
State
extends
{
[
K
:
string
]:
boolean
}
>
(
types
:
Types
,
property
:
keyof
State
=
'fetching'
)
=>
{
return
{
[
types
.
pending
]:
(
state
:
State
)
=>
{
state
[
property
]
=
true
as
any
},
[
types
.
fulfilled
]:
(
state
:
State
)
=>
{
state
[
property
]
=
false
as
any
},
[
types
.
rejected
]:
(
state
:
State
)
=>
{
state
[
property
]
=
false
as
any
},
}
}
export
const
getTypesThunkActions
=
<
Actions
>
(
actions
:
Actions
)
=>
{
type
Types
=
{
[
key
in
keyof
Actions
]:
{
pending
:
string
fulfilled
:
string
rejected
:
string
}
}
return
keys
(
actions
).
reduce
((
acc
,
curr
)
=>
{
const
thunkAction
=
actions
[
curr
as
keyof
Actions
]
as
unknown
as
ReturnType
<
typeof
createAsyncThunk
>
return
{
...
acc
,
[
curr
]:
{
pending
:
thunkAction
.
pending
.
type
,
fulfilled
:
thunkAction
.
fulfilled
.
type
,
rejected
:
thunkAction
.
rejected
.
type
,
},
}
},
{}
as
Types
)
}
export
const
getActionTypes
=
<
Actions
>
(
actions
:
Actions
)
=>
{
type
Types
=
{
[
key
in
keyof
Actions
]:
string
}
return
Object
.
keys
(
actions
).
reduce
((
acc
,
curr
)
=>
{
return
{
...
acc
,
[
curr
]:
`
${
actions
[
curr
as
keyof
Actions
]}
`
}
},
{}
as
Types
)
}
export
type
WithSuccess
<
T
,
A
=
void
>
=
T
&
{
onSuccess
?:
(
args
?:
A
)
=>
void
}
cli/web/src/utils/validators.ts
View file @
06b6c363
...
@@ -135,6 +135,11 @@ export function validateEmail(field: Field<string>): FieldValidation {
...
@@ -135,6 +135,11 @@ export function validateEmail(field: Field<string>): FieldValidation {
}
}
}
}
export
const
isValidCPF
=
(
text
:
string
)
=>
{
const
cpf
=
extractNumbers
(
text
)
return
cpf
.
length
===
11
}
export
function
validateDate
(
field
:
Field
<
Date
>
):
FieldValidation
{
export
function
validateDate
(
field
:
Field
<
Date
>
):
FieldValidation
{
try
{
try
{
if
(
field
.
value
!==
null
)
field
.
value
.
toISOString
()
if
(
field
.
value
!==
null
)
field
.
value
.
toISOString
()
...
...
cli/web/src/views/Login/Login.tsx
View file @
06b6c363
...
@@ -5,8 +5,6 @@ import { bindActionCreators, Dispatch } from 'redux'
...
@@ -5,8 +5,6 @@ import { bindActionCreators, Dispatch } from 'redux'
import
ButtonWithProgress
from
'@agiliza/components/atoms/ButtonWithProgress'
import
ButtonWithProgress
from
'@agiliza/components/atoms/ButtonWithProgress'
import
TextFieldWithIcon
from
'@agiliza/components/atoms/TextFieldWithIcon'
import
TextFieldWithIcon
from
'@agiliza/components/atoms/TextFieldWithIcon'
import
PopoverVersion
from
'@agiliza/components/molecules/PopoverVersion'
import
{
ConfigService
}
from
'@agiliza/curio/SessionManager'
import
{
StoreState
}
from
'@agiliza/redux'
import
{
StoreState
}
from
'@agiliza/redux'
import
{
isAuthenticated
}
from
'@agiliza/redux/session/selectors'
import
{
isAuthenticated
}
from
'@agiliza/redux/session/selectors'
import
{
actions
}
from
'@agiliza/redux/ui/login'
import
{
actions
}
from
'@agiliza/redux/ui/login'
...
@@ -24,11 +22,10 @@ interface Props extends BaseProps {
...
@@ -24,11 +22,10 @@ interface Props extends BaseProps {
authenticated
:
boolean
authenticated
:
boolean
fetching
:
boolean
fetching
:
boolean
loginRequest
:
typeof
actions
.
login
loginRequest
:
typeof
actions
.
login
service
?:
ConfigService
}
}
const
Login
=
(
props
:
Props
)
=>
{
const
Login
=
(
props
:
Props
)
=>
{
const
{
loginRequest
,
authenticated
,
service
,
fetching
}
=
props
const
{
loginRequest
,
authenticated
,
fetching
}
=
props
const
classes
=
useStyles
()
const
classes
=
useStyles
()
...
@@ -72,7 +69,7 @@ const Login = (props: Props) => {
...
@@ -72,7 +69,7 @@ const Login = (props: Props) => {
Entrar
Entrar
</
ButtonWithProgress
>
</
ButtonWithProgress
>
</
div
>
</
div
>
<
PopoverVersion
service=
{
service
}
/>
{
/* <PopoverVersion service={service} /> */
}
</
div
>
</
div
>
)
)
}
}
...
...
cli/web/src/views/Main/Main.tsx
View file @
06b6c363
...
@@ -4,8 +4,8 @@ import { Redirect, Route, RouteComponentProps, Switch, useLocation } from 'react
...
@@ -4,8 +4,8 @@ import { Redirect, Route, RouteComponentProps, Switch, useLocation } from 'react
import
AppBar
from
'@agiliza/components/molecules/AppBar'
import
AppBar
from
'@agiliza/components/molecules/AppBar'
import
CircularProgress
from
'@agiliza/components/molecules/CircularProgress'
import
CircularProgress
from
'@agiliza/components/molecules/CircularProgress'
import
Drawer
from
'@agiliza/components/molecules/Drawer'
import
Drawer
from
'@agiliza/components/molecules/Drawer'
import
{
actions
as
sessionActions
}
from
'@agiliza/redux/session'
import
{
actions
as
drawerActions
}
from
'@agiliza/redux/ui/drawer'
import
{
actions
as
drawerActions
}
from
'@agiliza/redux/ui/drawer'
import
{
actions
as
loginActions
}
from
'@agiliza/redux/ui/login'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
connect
,
{
ConnectedProps
}
from
'./connect'
import
connect
,
{
ConnectedProps
}
from
'./connect'
...
@@ -20,7 +20,7 @@ type BaseProps = RouteComponentProps & ConnectedProps & WithStyles<typeof styles
...
@@ -20,7 +20,7 @@ type BaseProps = RouteComponentProps & ConnectedProps & WithStyles<typeof styles
interface
Props
extends
BaseProps
{
interface
Props
extends
BaseProps
{
toggleDrawer
:
typeof
drawerActions
.
toggleDrawer
toggleDrawer
:
typeof
drawerActions
.
toggleDrawer
logout
:
typeof
sessio
nActions
.
logout
logout
:
typeof
logi
nActions
.
logout
}
}
const
Main
=
(
props
:
Props
)
=>
{
const
Main
=
(
props
:
Props
)
=>
{
...
@@ -40,7 +40,7 @@ const Main = (props: Props) => {
...
@@ -40,7 +40,7 @@ const Main = (props: Props) => {
<
Switch
>
<
Switch
>
<
Route
path=
{
PATHS
.
creditLines
}
render=
{
(
rProps
)
=>
<
SimulationCreditLines
{
...
rProps
}
/>
}
/>
<
Route
path=
{
PATHS
.
creditLines
}
render=
{
(
rProps
)
=>
<
SimulationCreditLines
{
...
rProps
}
/>
}
/>
<
Route
path=
{
PATHS
.
proposalData
}
render=
{
(
rProps
)
=>
<
ProposalData
{
...
rProps
}
/>
}
/>
<
Route
path=
{
PATHS
.
proposalData
}
render=
{
(
rProps
)
=>
<
ProposalData
{
...
rProps
}
/>
}
/>
<
Redirect
from=
"/"
to=
{
PATHS
.
proposalData
}
/>
<
Redirect
from=
"/"
to=
{
PATHS
.
creditLines
}
/>
</
Switch
>
</
Switch
>
</
Suspense
>
</
Suspense
>
</
div
>
</
div
>
...
...
cli/web/src/views/Main/connect.ts
View file @
06b6c363
...
@@ -2,9 +2,9 @@ import { connect } from 'react-redux'
...
@@ -2,9 +2,9 @@ import { connect } from 'react-redux'
import
{
bindActionCreators
,
Dispatch
}
from
'redux'
import
{
bindActionCreators
,
Dispatch
}
from
'redux'
import
{
StoreState
}
from
'@agiliza/redux'
import
{
StoreState
}
from
'@agiliza/redux'
import
{
actions
as
sessionActions
}
from
'@agiliza/redux/session'
import
{
actions
as
drawerActions
}
from
'@agiliza/redux/ui/drawer'
import
{
actions
as
drawerActions
}
from
'@agiliza/redux/ui/drawer'
import
{
isDrawerOpen
}
from
'@agiliza/redux/ui/drawer/selectors'
import
{
isDrawerOpen
}
from
'@agiliza/redux/ui/drawer/selectors'
import
{
actions
as
loginActions
}
from
'@agiliza/redux/ui/login'
import
{
actions
as
systemActions
,
selectors
as
systemSelectors
}
from
'@agiliza/redux/ui/system'
import
{
actions
as
systemActions
,
selectors
as
systemSelectors
}
from
'@agiliza/redux/ui/system'
export
interface
ConnectedProps
{
export
interface
ConnectedProps
{
...
@@ -12,7 +12,7 @@ export interface ConnectedProps {
...
@@ -12,7 +12,7 @@ export interface ConnectedProps {
fetchingMenu
:
boolean
fetchingMenu
:
boolean
fetchMenu
:
typeof
systemActions
.
fetchMenu
fetchMenu
:
typeof
systemActions
.
fetchMenu
toggleDrawer
:
typeof
drawerActions
.
toggleDrawer
toggleDrawer
:
typeof
drawerActions
.
toggleDrawer
logout
:
typeof
sessio
nActions
.
logout
logout
:
typeof
logi
nActions
.
logout
}
}
const
mapStateToProps
=
(
state
:
StoreState
)
=>
({
const
mapStateToProps
=
(
state
:
StoreState
)
=>
({
...
@@ -25,7 +25,7 @@ const mapDispatchToProps = (dispatch: Dispatch) =>
...
@@ -25,7 +25,7 @@ const mapDispatchToProps = (dispatch: Dispatch) =>
bindActionCreators
(
bindActionCreators
(
{
{
toggleDrawer
:
drawerActions
.
toggleDrawer
,
toggleDrawer
:
drawerActions
.
toggleDrawer
,
logout
:
sessio
nActions
.
logout
,
logout
:
logi
nActions
.
logout
,
fetchMenu
:
systemActions
.
fetchMenu
,
fetchMenu
:
systemActions
.
fetchMenu
,
},
},
dispatch
dispatch
...
...
cli/web/src/views/SimulationCreditLines/pages/CreditLinesList/CreditLinesList.tsx
View file @
06b6c363
import
React
,
{
useState
}
from
'react'
import
React
,
{
use
Effect
,
use
State
}
from
'react'
import
{
RouteComponentProps
}
from
'react-router'
import
{
RouteComponentProps
}
from
'react-router'
import
{
SimulationCategory
}
from
'@agiliza/api/domain'
import
{
extractCurrency
,
extractNumbers
}
from
'@agiliza/utils/extractors'
import
{
extractCurrency
,
extractNumbers
}
from
'@agiliza/utils/extractors'
import
{
formatCurrency
}
from
'@agiliza/utils/formatters'
import
{
formatCurrency
}
from
'@agiliza/utils/formatters'
import
{
import
{
Button
,
Button
,
CircularProgress
,
CircularProgress
,
IconButton
,
InputAdornment
,
InputAdornment
,
TextareaAutosize
,
TextareaAutosize
,
TextField
,
TextField
,
Typography
Typography
}
from
'@material-ui/core'
}
from
'@material-ui/core'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
{
Refresh
as
RefreshIcon
}
from
'@material-ui/icons'
import
{
Autocomplete
}
from
'@material-ui/lab'
import
{
Autocomplete
}
from
'@material-ui/lab'
import
{
creditLines
}
from
'../../../../__mocks__/creditLines'
import
{
CREDIT_LINES_PATHS
}
from
'../router'
import
{
CREDIT_LINES_PATHS
}
from
'../router'
import
{
connected
,
ConnectedProps
}
from
'./connect'
import
SliderField
from
'./SliderField'
import
SliderField
from
'./SliderField'
import
styles
from
'./styles'
import
styles
from
'./styles'
type
CreditLine
=
typeof
creditLines
[
0
]
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
&
RouteComponentProps
&
ConnectedProps
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
&
RouteComponentProps
interface
Props
extends
ExtendedProps
{
interface
Props
extends
ExtendedProps
{
fetching
:
boolean
fetching
:
boolean
}
}
const
CreditLinesList
:
React
.
FC
<
Props
>
=
(
props
)
=>
{
const
CreditLinesList
=
(
props
:
Props
)
=>
{
const
{
classes
,
fetching
,
history
,
match
}
=
props
const
{
classes
,
fetching
,
history
,
match
,
simulationCategories
}
=
props
useEffect
(()
=>
{
props
.
fetchSimulationCategories
()
},
[])
const
[
selected
CreditLine
,
setSelectedCreditLine
]
=
useState
<
CreditLine
|
null
>
(
null
)
const
[
selected
SimulCategory
,
setSelectedSimulCategory
]
=
useState
<
SimulationCategory
|
null
>
(
null
)
const
[
amount
,
setAmount
]
=
useState
(
'0'
)
const
[
amount
,
setAmount
]
=
useState
(
'0'
)
const
[
paymentMonths
,
setPaymentMonths
]
=
useState
(
0
)
const
[
paymentMonths
,
setPaymentMonths
]
=
useState
(
0
)
const
[
graceMonths
,
setGraceMonths
]
=
useState
(
0
)
const
[
graceMonths
,
setGraceMonths
]
=
useState
(
0
)
const
parentPath
=
match
.
path
.
substring
(
0
,
match
.
path
.
lastIndexOf
(
'/'
))
const
parentPath
=
match
.
path
.
substring
(
0
,
match
.
path
.
lastIndexOf
(
'/'
))
const
handleSimulate
=
()
=>
{
const
handleSimulate
=
()
=>
{
if
(
selectedCreditLine
)
history
.
push
({
pathname
:
parentPath
+
CREDIT_LINES_PATHS
.
simulation
,
state
:
{
id
:
selectedCreditLine
.
id
}
})
if
(
selectedSimulCategory
)
props
.
getSubproducts
({
idModality
:
selectedSimulCategory
.
id
,
creditValue
:
Number
(
amount
),
idGracePeriod
:
graceMonths
.
toString
(),
installmentsNumber
:
paymentMonths
,
onSuccess
:
(
subPdcs
)
=>
{
if
(
subPdcs
&&
subPdcs
.
length
>
0
)
history
.
push
({
pathname
:
parentPath
+
CREDIT_LINES_PATHS
.
simulation
})
else
props
.
setErrorMessage
(
'Nenhum subproduto encontrado. Tente novamente com outros valores...'
)
},
})
}
}
return
(
return
(
...
@@ -47,42 +62,53 @@ const CreditLinesList: React.FC<Props> = (props) => {
...
@@ -47,42 +62,53 @@ const CreditLinesList: React.FC<Props> = (props) => {
<
Typography
variant=
"h5"
className=
{
classes
.
title
}
>
<
Typography
variant=
"h5"
className=
{
classes
.
title
}
>
Escolha a melhor linha de crédito para você e clique em simular!
Escolha a melhor linha de crédito para você e clique em simular!
</
Typography
>
</
Typography
>
<
Autocomplete
<
CreditLine
>
<
Autocomplete
<
SimulationCategory
>
id="credit-lines"
id="credit-lines"
className=
{
classes
.
creditLinesAutocomplete
}
className=
{
classes
.
creditLinesAutocomplete
}
options=
{
creditLin
es
}
options=
{
simulationCategori
es
}
getOptionLabel=
{
(
option
)
=>
option
.
name
}
getOptionLabel=
{
(
option
)
=>
option
.
description
}
getOptionSelected=
{
(
opt
,
val
)
=>
opt
.
id
===
selected
CreditLine
?.
id
}
getOptionSelected=
{
(
opt
,
val
)
=>
opt
.
id
===
selected
SimulCategory
?.
id
}
noOptionsText="Nenhuma linha encontrad
o
"
noOptionsText="Nenhuma linha encontrad
a
"
value=
{
selected
CreditLine
}
value=
{
selected
SimulCategory
}
onChange=
{
(
_
,
opt
)
=>
{
onChange=
{
(
_
,
opt
)
=>
{
setSelected
CreditLine
(
opt
||
null
)
setSelected
SimulCategory
(
opt
||
null
)
setAmount
(
opt
?.
amount
.
min
.
toString
()
||
'0'
)
//
setAmount(opt?.amount.min.toString() || '0')
setPaymentMonths
(
opt
?.
paymentMonths
.
min
||
0
)
setPaymentMonths
(
opt
?.
maxInstallment
||
0
)
setGraceMonths
(
opt
?.
graceMonths
.
min
||
0
)
setGraceMonths
(
opt
?.
maxGraceMonths
||
0
)
}
}
}
}
renderInput=
{
(
params
)
=>
{
renderInput=
{
(
params
)
=>
{
const
isValid
=
React
.
isValidElement
(
params
.
InputProps
.
endAdornment
)
const
isValid
=
React
.
isValidElement
(
params
.
InputProps
.
endAdornment
)
const
fetchingEndAdornment
=
(
<
InputAdornment
position=
"end"
style=
{
{
flex
:
'1'
,
display
:
'flex'
,
justifyContent
:
'flex-end'
}
}
>
<
CircularProgress
size=
{
20
}
/>
</
InputAdornment
>
)
const
validEndAdornment
=
React
.
cloneElement
(
params
.
InputProps
.
endAdornment
as
React
.
ReactElement
,
{
style
:
{
marginRight
:
'1rem'
},
})
const
refreshEndAdorment
=
(
<
InputAdornment
position=
"end"
style=
{
{
flex
:
'1'
,
display
:
'flex'
,
justifyContent
:
'flex-end'
}
}
>
<
IconButton
onClick=
{
()
=>
props
.
fetchSimulationCategories
()
}
>
<
RefreshIcon
/>
</
IconButton
>
</
InputAdornment
>
)
return
(
return
(
<
TextField
<
TextField
{
...
params
}
{
...
params
}
id=
"select-patient-id"
id=
"select-patient-id"
label=
"
Selecione ou Digite Id Paciente
"
label=
"
Linha de crédito
"
variant=
"outlined"
variant=
"outlined"
InputProps=
{
{
InputProps=
{
{
ref
:
params
.
InputProps
.
ref
,
ref
:
params
.
InputProps
.
ref
,
endAdornment
:
fetching
?
(
endAdornment
:
fetching
<
InputAdornment
position=
"end"
style=
{
{
flex
:
'1'
,
display
:
'flex'
,
justifyContent
:
'flex-end'
}
}
>
?
fetchingEndAdornment
<
CircularProgress
size=
{
20
}
/>
:
!
simulationCategories
.
length
</
InputAdornment
>
?
refreshEndAdorment
)
:
isValid
?
(
:
isValid
React
.
cloneElement
(
params
.
InputProps
.
endAdornment
as
React
.
ReactElement
,
{
?
validEndAdornment
style
:
{
marginRight
:
'1rem'
},
:
params
.
InputProps
.
endAdornment
,
})
)
:
(
params
.
InputProps
.
endAdornment
),
}
}
}
}
/>
/>
)
)
...
@@ -91,7 +117,7 @@ const CreditLinesList: React.FC<Props> = (props) => {
...
@@ -91,7 +117,7 @@ const CreditLinesList: React.FC<Props> = (props) => {
<
TextField
<
TextField
className=
{
classes
.
description
}
className=
{
classes
.
description
}
label=
"Descrição da linha de crédito"
label=
"Descrição da linha de crédito"
value=
{
selected
CreditLine
?.
informations
||
''
}
value=
{
selected
SimulCategory
?.
fullDescription
||
''
}
rows=
{
5
}
rows=
{
5
}
multiline
multiline
contentEditable=
{
false
}
contentEditable=
{
false
}
...
@@ -105,89 +131,93 @@ const CreditLinesList: React.FC<Props> = (props) => {
...
@@ -105,89 +131,93 @@ const CreditLinesList: React.FC<Props> = (props) => {
<
SliderField
<
SliderField
className=
{
classes
.
sliderField
}
className=
{
classes
.
sliderField
}
title=
"De quanto você precisa?"
title=
"De quanto você precisa?"
min=
{
selectedCreditLine
?.
amount
.
min
||
0
}
// sliderProps={{
max=
{
selectedCreditLine
?.
amount
.
max
||
5000
}
// min: 0,
marks=
{
// max: 5000,
selectedCreditLine
// marks: selectedSimulCategory
?
[
// ? [
{
value
:
selectedCreditLine
.
amount
.
min
,
label
:
formatCurrency
(
selectedCreditLine
.
amount
.
min
.
toString
())
},
// { value: 0, label: formatCurrency('0') },
{
value
:
selectedCreditLine
.
amount
.
max
,
label
:
formatCurrency
(
selectedCreditLine
.
amount
.
max
.
toString
())
},
// { value: 99999, label: formatCurrency('99999') },
]
// // { value: selectedSimulCategory.amount.min, label: formatCurrency(selectedSimulCategory.amount.min.toString()) },
:
[
// // { value: selectedSimulCategory.amount.max, label: formatCurrency(selectedSimulCategory.amount.max.toString()) },
{
value
:
0
,
label
:
formatCurrency
(
'0'
)
},
// ]
{
value
:
5000
,
label
:
''
},
// : [
]
// { value: 0, label: formatCurrency('0') },
}
// { value: 5000, label: '' },
valueSlider=
{
Number
(
amount
)
}
// ],
// value: Number(amount),
// step: 0.01,
// onChange: (_, value) => setAmount((value as number).toString()),
// }}
valueField=
{
formatCurrency
(
amount
.
toString
(),
true
)
}
valueField=
{
formatCurrency
(
amount
.
toString
(),
true
)
}
step=
{
0.01
}
disabled=
{
!
selectedSimulCategory
}
disabled=
{
!
selectedCreditLine
}
onChangeSlider=
{
(
_
,
value
)
=>
setAmount
((
value
as
number
).
toString
())
}
onChangeField=
{
(
evt
)
=>
setAmount
(
extractCurrency
(
evt
.
target
.
value
))
}
onChangeField=
{
(
evt
)
=>
setAmount
(
extractCurrency
(
evt
.
target
.
value
))
}
onBlurField=
{
(
evt
)
=>
{
onBlurField=
{
(
evt
)
=>
{
const
amountValue
=
extractCurrency
(
evt
.
target
.
value
)
//
const amountValue = extractCurrency(evt.target.value)
if
(
selectedCreditLine
)
// if (selectedSimulCategory
)
setAmount
(
Number
(
amountValue
)
<=
selectedCreditLine
.
amount
.
max
?
amountValue
:
selectedCreditLine
.
amount
.
max
.
toString
())
// setAmount(Number(amountValue) <= selectedSimulCategory.amount.max ? amountValue : selectedSimulCategory
.amount.max.toString())
}
}
}
}
/>
/>
<
SliderField
<
SliderField
className=
{
classes
.
sliderField
}
className=
{
classes
.
sliderField
}
title=
"Quantos meses para pagar?"
title=
"Quantos meses para pagar?"
min=
{
selectedCreditLine
?.
paymentMonths
.
min
||
0
}
sliderProps=
{
{
max=
{
selectedCreditLine
?.
paymentMonths
.
max
||
12
}
min
:
0
,
marks=
{
max
:
selectedSimulCategory
?.
maxInstallment
||
12
,
selectedCreditLine
marks
:
selectedSimulCategory
?
[
?
[
{
value
:
selectedCreditLine
.
paymentMonths
.
min
,
label
:
`${selectedCreditLine.paymentMonths.min
} meses`
},
{
value
:
0
,
label
:
`${0
} meses`
},
{
value
:
selected
CreditLine
.
paymentMonths
.
max
,
label
:
`${selectedCreditLine.paymentMonths.max
} meses`
},
{
value
:
selected
SimulCategory
?.
maxInstallment
,
label
:
`${selectedSimulCategory?.maxInstallment
} meses`
},
]
]
:
[
:
[
{
value
:
0
,
label
:
'0 meses'
},
{
value
:
0
,
label
:
'0 meses'
},
{
value
:
12
,
label
:
''
},
{
value
:
12
,
label
:
''
},
]
],
}
value
:
Number
(
paymentMonths
),
valueSlider=
{
Number
(
paymentMonths
)
}
onChange
:
(
_
,
value
)
=>
setPaymentMonths
(
value
as
number
),
valueField=
{
paymentMonths
.
toString
()
+
' meses'
}
}
}
disabled=
{
!
selectedCreditLine
}
valueField=
{
paymentMonths
.
toString
()
}
onChangeSlider=
{
(
_
,
value
)
=>
setPaymentMonths
(
value
as
number
)
}
suffix=
{
`m${paymentMonths > 1 ? 'e' : 'ê'}s${paymentMonths > 1 ? 'es' : ''}`
}
onChangeField=
{
(
evt
)
=>
setPaymentMonths
(
Number
(
evt
.
target
.
value
))
}
disabled=
{
!
selectedSimulCategory
}
onChangeField=
{
(
evt
)
=>
setPaymentMonths
(
Number
(
extractNumbers
(
evt
.
target
.
value
)))
}
onBlurField=
{
(
evt
)
=>
{
onBlurField=
{
(
evt
)
=>
{
const
paymentMonthsValue
=
Number
(
extractNumbers
(
evt
.
target
.
value
))
const
paymentMonthsValue
=
Number
(
extractNumbers
(
evt
.
target
.
value
))
if
(
selected
CreditLine
)
if
(
selected
SimulCategory
)
setPaymentMonths
(
setPaymentMonths
(
paymentMonthsValue
<=
selected
CreditLine
.
paymentMonths
.
max
?
paymentMonthsValue
:
selectedCreditLine
.
paymentMonths
.
max
paymentMonthsValue
<=
selected
SimulCategory
.
maxInstallment
?
paymentMonthsValue
:
selectedSimulCategory
.
maxInstallment
)
)
}
}
}
}
/>
/>
<
SliderField
<
SliderField
className=
{
classes
.
sliderField
}
className=
{
classes
.
sliderField
}
title=
"Quantos
mese
s de carência?"
title=
"Quantos
dia
s de carência?"
min=
{
selectedCreditLine
?.
graceMonths
.
min
||
0
}
sliderProps=
{
{
max=
{
selectedCreditLine
?.
graceMonths
.
max
||
12
}
min
:
0
,
marks=
{
max
:
selectedSimulCategory
?.
maxGraceMonths
||
12
,
selectedCreditLine
marks
:
selectedSimulCategory
?
[
?
[
{
value
:
selectedCreditLine
.
graceMonths
.
min
,
label
:
`${selectedCreditLine.graceMonths.min} mese
s`
},
{
value
:
0
,
label
:
`${0} dia
s`
},
{
value
:
selected
CreditLine
.
graceMonths
.
max
,
label
:
`${selectedCreditLine.graceMonths.max} mese
s`
},
{
value
:
selected
SimulCategory
?.
maxGraceMonths
,
label
:
`${selectedSimulCategory?.maxGraceMonths} dia
s`
},
]
]
:
[
:
[
{
value
:
0
,
label
:
'0
mese
s'
},
{
value
:
0
,
label
:
'0
dia
s'
},
{
value
:
12
,
label
:
''
},
{
value
:
12
,
label
:
''
},
]
],
}
value
:
Number
(
graceMonths
),
valueSlider=
{
Number
(
graceMonths
)
}
onChange
:
(
_
,
value
)
=>
setGraceMonths
(
value
as
number
),
valueField=
{
graceMonths
.
toString
()
+
' meses'
}
}
}
disabled=
{
!
selectedCreditLine
}
valueField=
{
graceMonths
.
toString
()
}
onChangeSlider=
{
(
_
,
value
)
=>
setGraceMonths
(
value
as
number
)
}
suffix=
{
`dia${graceMonths > 1 ? 's' : ''}`
}
onChangeField=
{
(
evt
)
=>
setGraceMonths
(
Number
(
evt
.
target
.
value
))
}
disabled=
{
!
selectedSimulCategory
}
onChangeField=
{
(
evt
)
=>
setGraceMonths
(
Number
(
extractNumbers
(
evt
.
target
.
value
)))
}
onBlurField=
{
(
evt
)
=>
{
onBlurField=
{
(
evt
)
=>
{
const
graceMonthsValue
=
Number
(
extractNumbers
(
evt
.
target
.
value
))
const
graceMonthsValue
=
Number
(
extractNumbers
(
evt
.
target
.
value
))
if
(
selected
CreditLine
)
if
(
selected
SimulCategory
)
setGraceMonths
(
graceMonthsValue
<=
selected
CreditLine
.
graceMonths
.
max
?
graceMonthsValue
:
selectedCreditLine
.
graceMonths
.
max
)
setGraceMonths
(
graceMonthsValue
<=
selected
SimulCategory
.
maxGraceMonths
?
graceMonthsValue
:
selectedSimulCategory
.
maxGraceMonths
)
}
}
}
}
/>
/>
<
div
className=
{
classes
.
btnContainer
}
>
<
div
className=
{
classes
.
btnContainer
}
>
<
Button
disabled=
{
!
selected
CreditLine
}
variant=
"contained"
color=
"secondary"
onClick=
{
handleSimulate
}
>
<
Button
disabled=
{
!
selected
SimulCategory
}
variant=
"contained"
color=
"secondary"
onClick=
{
handleSimulate
}
>
Simular
Simular
</
Button
>
</
Button
>
</
div
>
</
div
>
...
@@ -197,4 +227,4 @@ const CreditLinesList: React.FC<Props> = (props) => {
...
@@ -197,4 +227,4 @@ const CreditLinesList: React.FC<Props> = (props) => {
)
)
}
}
export default
withStyles(styles)(CreditLinesList
)
export default
connected(withStyles(styles)(CreditLinesList)
)
cli/web/src/views/SimulationCreditLines/pages/CreditLinesList/SliderField.tsx
View file @
06b6c363
...
@@ -6,35 +6,33 @@ type ExtendedProps = Record<string, unknown>
...
@@ -6,35 +6,33 @@ type ExtendedProps = Record<string, unknown>
interface
Props
extends
ExtendedProps
{
interface
Props
extends
ExtendedProps
{
title
:
string
title
:
string
min
:
SliderProps
[
'min'
]
max
:
SliderProps
[
'max'
]
marks
?:
SliderProps
[
'marks'
]
valueSlider
:
number
valueField
:
string
valueField
:
string
step
?:
SliderProps
[
'step'
]
sliderProps
?:
Pick
<
SliderProps
,
'min'
|
'max'
|
'marks'
|
'step'
>
&
{
onChangeSlider
:
(
event
:
React
.
ChangeEvent
<
Record
<
string
,
unknown
>>
,
value
:
number
|
number
[])
=>
void
onChange
:
(
event
:
React
.
ChangeEvent
<
Record
<
string
,
unknown
>>
,
value
:
number
|
number
[])
=>
void
value
:
number
}
disabled
:
boolean
onChangeField
:
TextFieldProps
[
'onChange'
]
onChangeField
:
TextFieldProps
[
'onChange'
]
onBlurField
:
TextFieldProps
[
'onBlur'
]
onBlurField
:
TextFieldProps
[
'onBlur'
]
disabled
:
boolean
className
?:
string
className
?:
string
suffix
?:
string
}
}
const
SliderField
=
(
props
:
Props
)
=>
{
const
SliderField
=
(
props
:
Props
)
=>
{
const
{
className
,
title
,
min
,
max
,
marks
,
valueSlider
,
valueField
,
step
=
1
,
disabled
,
onChangeSlider
,
onChangeField
,
onBlurField
}
=
props
const
{
className
,
title
,
valueField
,
disabled
,
onChangeField
,
onBlurField
,
suffix
,
sliderProps
}
=
props
const
{
step
=
1
}
=
sliderProps
||
{
step
:
1
}
return
(
return
(
<
div
className=
{
className
}
>
<
div
className=
{
className
}
>
<
Typography
gutterBottom
>
{
title
}
</
Typography
>
<
Typography
gutterBottom
>
{
title
}
</
Typography
>
<
Slider
{
sliderProps
&&
<
Slider
{
...
sliderProps
}
disabled=
{
disabled
}
step=
{
step
}
/>
}
<
TextField
style=
{
{
width
:
'18%'
}
}
disabled=
{
disabled
}
disabled=
{
disabled
}
min=
{
min
}
value=
{
valueField
}
max=
{
max
}
onChange=
{
onChangeField
}
value=
{
valueSlider
}
onBlur=
{
onBlurField
}
onChange=
{
onChangeSlider
}
InputProps=
{
{
endAdornment
:
suffix
&&
<
Typography
>
{
suffix
}
</
Typography
>
}
}
// valueLabelDisplay="auto"
step=
{
step
}
marks=
{
marks
}
/>
/>
<
TextField
style=
{
{
width
:
'12%'
}
}
disabled=
{
disabled
}
value=
{
valueField
}
onChange=
{
onChangeField
}
onBlur=
{
onBlurField
}
/>
</
div
>
</
div
>
)
)
}
}
...
...
cli/web/src/views/SimulationCreditLines/pages/CreditLinesList/connect.ts
0 → 100644
View file @
06b6c363
import
{
connect
}
from
'react-redux'
import
{
SimulationCategory
}
from
'@agiliza/api/domain'
import
{
StoreState
}
from
'@agiliza/redux'
import
*
as
entSimulationContext
from
'@agiliza/redux/entities/simulation/context'
import
{
actions
as
errorActions
}
from
'@agiliza/redux/ui/error'
import
*
as
ucSimulation
from
'@agiliza/redux/useCases/simulation'
import
{
bindActionCreators
,
Dispatch
}
from
'@reduxjs/toolkit'
export
interface
ConnectedProps
{
fetching
:
boolean
simulationCategories
:
SimulationCategory
[]
fetchSimulationCategories
:
typeof
ucSimulation
.
actions
.
fetchSimulationCategories
getSubproducts
:
typeof
ucSimulation
.
actions
.
getSubproducts
setErrorMessage
:
typeof
errorActions
.
setErrorMessage
}
type
StateProps
=
Pick
<
ConnectedProps
,
'fetching'
|
'simulationCategories'
>
type
DispatchProps
=
Pick
<
ConnectedProps
,
'fetchSimulationCategories'
|
'getSubproducts'
|
'setErrorMessage'
>
const
mapStateToProps
=
(
state
:
StoreState
):
StateProps
=>
({
fetching
:
ucSimulation
.
selectors
.
isFetching
(
state
.
useCases
.
simulation
),
simulationCategories
:
entSimulationContext
.
selectors
.
getSimulationCategories
(
state
.
entities
.
simulation
.
context
),
})
const
mapDispatchToProps
=
(
dispatch
:
Dispatch
):
DispatchProps
=>
bindActionCreators
(
{
fetchSimulationCategories
:
ucSimulation
.
actions
.
fetchSimulationCategories
,
getSubproducts
:
ucSimulation
.
actions
.
getSubproducts
,
setErrorMessage
:
errorActions
.
setErrorMessage
,
},
dispatch
)
export
const
connected
=
connect
(
mapStateToProps
,
mapDispatchToProps
)
cli/web/src/views/SimulationCreditLines/pages/Simulation/CreditLinesInfo/CreditLinesInfo.tsx
View file @
06b6c363
import
React
,
{
useEffect
,
use
Memo
}
from
'react'
import
React
,
{
useEffect
,
use
State
}
from
'react'
import
{
SubProduct
}
from
'@agiliza/api/domain'
import
{
formatCurrency
}
from
'@agiliza/utils/formatters'
import
{
formatCurrency
}
from
'@agiliza/utils/formatters'
import
{
Grid
}
from
'@material-ui/core'
import
{
SelectField
}
from
'@curio/components'
import
{
Button
,
Grid
}
from
'@material-ui/core'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
{
c
reditLinesData
}
from
'../../../../../__mocks__/creditLines
'
import
{
c
onnected
,
ConnectedProps
}
from
'./connect
'
import
GridLine
from
'./GridLine'
import
GridLine
from
'./GridLine'
import
InstallmentsDialog
from
'./InstallmentsDialog'
import
styles
from
'./styles'
import
styles
from
'./styles'
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
&
ConnectedProps
interface
Props
extends
ExtendedProps
{
interface
Props
extends
ExtendedProps
{
id
:
string
onChangeCanGoForward
:
(
vl
:
boolean
)
=>
void
onChangeCanGoForward
:
(
vl
:
boolean
)
=>
void
}
}
const
CreditLinesInfo
=
(
props
:
Props
)
=>
{
const
CreditLinesInfo
=
(
props
:
Props
)
=>
{
const
{
classes
,
id
,
onChangeCanGoForward
}
=
props
const
{
classes
,
onChangeCanGoForward
,
subproducts
}
=
props
const
creditLine
=
useMemo
(()
=>
creditLinesData
[
id
],
[
id
])
const
[
selectedSP
,
setSelectedSP
]
=
useState
<
SubProduct
|
undefined
>
()
const
[
open
,
setOpen
]
=
useState
(
false
)
useEffect
(()
=>
{
useEffect
(()
=>
{
onChangeCanGoForward
(
true
)
onChangeCanGoForward
(
!!
selectedSP
)
},
[])
},
[
selectedSP
])
return
(
return
(
<
div
className=
{
classes
.
contentContainer
}
>
<
div
className=
{
classes
.
contentContainer
}
>
<
div
className=
{
classes
.
content
}
>
<
div
className=
{
classes
.
content
}
>
<
SelectField
id=
"subproducts"
className=
{
classes
.
selectField
}
label=
"Opções de Subproduto"
items=
{
subproducts
.
map
((
sp
)
=>
({
label
:
sp
.
description
||
''
,
value
:
sp
.
id
}))
}
value=
{
selectedSP
?.
id
||
''
}
onChange=
{
(
value
)
=>
{
const
subprd
=
subproducts
.
find
((
sp
)
=>
sp
.
id
===
value
)
setSelectedSP
(
subprd
)
}
}
shrink=
{
false
}
/>
<
Grid
container
className=
{
classes
.
gridContainer
}
>
<
Grid
container
className=
{
classes
.
gridContainer
}
>
<
GridLine
label=
"Número de parcelas"
value=
{
creditLine
?.
paymentMonths
}
/>
<
GridLine
label=
"Número de parcelas"
value=
{
selectedSP
?.
maxAmountInstallment
||
''
}
/>
<
GridLine
label=
"Valor das parcelas"
value=
{
formatCurrency
(
creditLine
?.
amount
.
toFixed
(
2
))
}
/>
{
/* <GridLine label="Valor das parcelas" value={formatCurrency(selectedSP?.amount.toFixed(2))} /> */
}
<
GridLine
label=
"Taxa de juros"
value=
{
`${creditLine?.interestRate} %`
}
/>
<
GridLine
label=
"Taxa de juros"
value=
{
selectedSP
?.
fee
?
`${selectedSP?.fee} %`
:
''
}
/>
<
GridLine
label=
"Custo efetivo total (CET)"
value=
{
`${creditLine?.effectiveTotalCost} %`
}
/>
<
GridLine
label=
"Custo efetivo total (CET)"
value=
{
selectedSP
?.
IOF
!==
undefined
?
`${selectedSP?.IOF} %`
:
''
}
/>
<
GridLine
label=
"Taxa abertura crédito (TAC)"
value=
{
formatCurrency
(
creditLine
?.
openingCreditRate
.
toFixed
(
2
))
}
/>
<
GridLine
label=
"Taxa abertura crédito (TAC)"
value=
{
formatCurrency
(
selectedSP
?.
TAC
?
.
toFixed
(
2
))
}
/>
</
Grid
>
</
Grid
>
<
Button
variant=
"text"
onClick=
{
()
=>
setOpen
(
true
)
}
disabled=
{
!
selectedSP
}
>
Exibir opções de parcelamento
</
Button
>
<
InstallmentsDialog
open=
{
open
}
onClose=
{
()
=>
setOpen
(
false
)
}
installmentOptions=
{
selectedSP
?.
installementOptions
}
/>
</
div
>
</
div
>
</
div
>
</
div
>
)
)
}
}
export
default
withStyles
(
styles
)(
CreditLinesInfo
)
export
default
connected
(
withStyles
(
styles
)(
CreditLinesInfo
)
)
cli/web/src/views/SimulationCreditLines/pages/Simulation/CreditLinesInfo/InstallmentsDialog/InstallmentsDialog.tsx
0 → 100644
View file @
06b6c363
import
React
from
'react'
import
{
InstallmentOption
}
from
'@agiliza/api/domain'
import
{
formatCurrency
}
from
'@agiliza/utils/formatters'
import
{
Button
,
Dialog
,
DialogActions
,
DialogContent
,
DialogProps
,
DialogTitle
,
Grid
,
Typography
}
from
'@material-ui/core'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
styles
from
'./styles'
type
ExtendedProps
=
Pick
<
DialogProps
,
'open'
>
&
WithStyles
<
typeof
styles
>
interface
Props
extends
ExtendedProps
{
onClose
:
()
=>
void
installmentOptions
?:
InstallmentOption
[]
}
const
InstallmentsDialog
=
(
props
:
Props
)
=>
{
const
{
classes
,
open
,
onClose
,
installmentOptions
}
=
props
return
(
<
Dialog
onClose=
{
onClose
}
aria
-
labelledby=
"simple-dialog-title"
open=
{
open
}
PaperProps=
{
{
className
:
classes
.
dialog
}
}
>
<
DialogTitle
>
Tipos de parcelamento
</
DialogTitle
>
<
DialogContent
>
<
Grid
container
className=
{
classes
.
gridContainer
}
>
<
Grid
item
xs=
{
6
}
>
<
Typography
className=
{
classes
.
gridHeaderText
}
>
Número de parcelas
</
Typography
>
</
Grid
>
<
Grid
item
xs=
{
3
}
>
<
Typography
className=
{
classes
.
gridHeaderText
}
>
Valor parcela
</
Typography
>
</
Grid
>
<
Grid
item
xs=
{
3
}
>
<
Typography
className=
{
classes
.
gridHeaderText
}
>
Valor total
</
Typography
>
</
Grid
>
</
Grid
>
{
installmentOptions
?.
map
((
iO
)
=>
(
<
Grid
container
item
xs=
{
12
}
key=
{
iO
.
id
}
>
<
Grid
item
xs=
{
6
}
>
{
iO
.
installmentAmount
&&
`${iO.installmentAmount || ''} parcela${iO.installmentAmount > 1 ? 's' : ''}`
}
</
Grid
>
<
Grid
item
xs=
{
3
}
>
{
formatCurrency
(
iO
.
installmentValue
?.
toString
()
||
''
)
}
</
Grid
>
<
Grid
item
xs=
{
3
}
>
{
formatCurrency
(
iO
.
netValue
?.
toString
()
||
''
)
}
</
Grid
>
{
/* <GridLine label="Número de parcelas" value={iO.installmentAmount || ''} />
<GridLine label="Valor de cada parcela" value={iO.installmentValue || ''} />
<GridLine label="Valor total" value={iO.netValue || ''} /> */
}
</
Grid
>
))
}
</
DialogContent
>
<
DialogActions
>
<
Button
onClick=
{
onClose
}
>
Fechar
</
Button
>
</
DialogActions
>
</
Dialog
>
)
}
export
default
withStyles
(
styles
)(
InstallmentsDialog
)
cli/web/src/views/SimulationCreditLines/pages/Simulation/CreditLinesInfo/InstallmentsDialog/index.ts
0 → 100644
View file @
06b6c363
export
{
default
}
from
'./InstallmentsDialog'
export
*
from
'./InstallmentsDialog'
cli/web/src/views/SimulationCreditLines/pages/Simulation/CreditLinesInfo/InstallmentsDialog/styles.ts
0 → 100644
View file @
06b6c363
import
{
Theme
}
from
'@material-ui/core/styles'
import
{
createStyles
}
from
'@material-ui/styles'
import
sharedStyles
from
'../styles'
// eslint-disable-next-line
export
default
(
theme
:
Theme
)
=>
createStyles
({
...
sharedStyles
(
theme
),
gridContainer
:
{
marginBottom
:
theme
.
spacing
(
1
)
},
dialog
:
{
height
:
'45%'
,
width
:
'65%'
},
gridHeaderText
:
{
fontWeight
:
'bold'
},
})
cli/web/src/views/SimulationCreditLines/pages/Simulation/CreditLinesInfo/connect.ts
0 → 100644
View file @
06b6c363
import
{
connect
}
from
'react-redux'
import
{
SubProduct
}
from
'@agiliza/api/domain'
import
{
StoreState
}
from
'@agiliza/redux'
import
*
as
entSimulation
from
'@agiliza/redux/entities/simulation/simulation'
export
interface
ConnectedProps
{
subproducts
:
SubProduct
[]
}
type
StateProps
=
Pick
<
ConnectedProps
,
'subproducts'
>
// type DispatchProps = Record<string, any>
const
mapStateToProps
=
(
state
:
StoreState
):
StateProps
=>
({
subproducts
:
entSimulation
.
selectors
.
getSubproducts
(
state
.
entities
.
simulation
.
simulation
),
})
// const mapDispatchToProps = (dispatch: Dispatch): DispatchProps => bindActionCreators({}, dispatch)
export
const
connected
=
connect
(
mapStateToProps
)
cli/web/src/views/SimulationCreditLines/pages/Simulation/CreditLinesInfo/styles.ts
View file @
06b6c363
...
@@ -7,6 +7,7 @@ import sharedStyles from '../styles'
...
@@ -7,6 +7,7 @@ import sharedStyles from '../styles'
export
default
(
theme
:
Theme
)
=>
export
default
(
theme
:
Theme
)
=>
createStyles
({
createStyles
({
...
sharedStyles
(
theme
),
...
sharedStyles
(
theme
),
gridContainer
:
{},
gridContainer
:
{
marginBottom
:
theme
.
spacing
(
2
)
},
gridItem
:
{
whiteSpace
:
'nowrap'
},
gridItem
:
{
whiteSpace
:
'nowrap'
},
selectField
:
{
marginBottom
:
theme
.
spacing
(
2
)
},
})
})
cli/web/src/views/SimulationCreditLines/pages/Simulation/Simulation.tsx
View file @
06b6c363
import
React
,
{
useMemo
,
useState
}
from
'react'
import
React
,
{
useMemo
,
useState
}
from
'react'
import
{
RouteComponentProps
,
useLocation
}
from
'react-router'
import
{
RouteComponentProps
}
from
'react-router'
import
{
PATHS
}
from
'@agiliza/views/Main/DrawerItems'
import
{
PATHS
}
from
'@agiliza/views/Main/DrawerItems'
import
{
Button
,
Step
,
StepLabel
,
Stepper
}
from
'@material-ui/core'
import
{
Button
,
Step
,
StepLabel
,
Stepper
}
from
'@material-ui/core'
...
@@ -12,16 +12,15 @@ import {
...
@@ -12,16 +12,15 @@ import {
import
CreditLinesInfo
from
'./CreditLinesInfo'
import
CreditLinesInfo
from
'./CreditLinesInfo'
import
styles
from
'./styles'
import
styles
from
'./styles'
import
UserForm
from
'./UserForm'
import
UserForm
from
'./UserForm'
import
VerificationCode
from
'./VerificationCode'
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
&
RouteComponentProps
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
&
RouteComponentProps
interface
Props
extends
ExtendedProps
{}
interface
Props
extends
ExtendedProps
{}
const
Simulation
=
(
props
:
Props
)
=>
{
const
Simulation
=
(
props
:
Props
)
=>
{
const
{
classes
,
history
}
=
props
const
{
classes
,
...
routerProps
}
=
props
const
{
history
}
=
routerProps
// const theme = useTheme()
// const theme = useTheme()
const
{
state
:
lState
}
=
useLocation
<
{
id
:
string
}
>
()
const
[
activeStep
,
setActiveStep
]
=
useState
(
0
)
const
[
activeStep
,
setActiveStep
]
=
useState
(
0
)
const
[
canGoForward
,
setCanGoForward
]
=
useState
(
true
)
const
[
canGoForward
,
setCanGoForward
]
=
useState
(
true
)
...
@@ -32,11 +31,9 @@ const Simulation = (props: Props) => {
...
@@ -32,11 +31,9 @@ const Simulation = (props: Props) => {
const
renderStep
=
(
step
:
number
)
=>
{
const
renderStep
=
(
step
:
number
)
=>
{
switch
(
step
)
{
switch
(
step
)
{
case
0
:
case
0
:
return
<
CreditLinesInfo
id=
{
lState
.
id
}
onChangeCanGoForward=
{
handleChangeCanGoForward
}
/>
return
<
CreditLinesInfo
onChangeCanGoForward=
{
handleChangeCanGoForward
}
/>
case
1
:
case
1
:
return
<
UserForm
onChangeCanGoForward=
{
handleChangeCanGoForward
}
/>
return
<
UserForm
onChangeCanGoForward=
{
handleChangeCanGoForward
}
/>
case
2
:
return
<
VerificationCode
onChangeCanGoForward=
{
handleChangeCanGoForward
}
/>
}
}
}
}
...
@@ -49,7 +46,7 @@ const Simulation = (props: Props) => {
...
@@ -49,7 +46,7 @@ const Simulation = (props: Props) => {
setActiveStep
((
prevActiveStep
)
=>
prevActiveStep
-
1
)
setActiveStep
((
prevActiveStep
)
=>
prevActiveStep
-
1
)
}
}
const
steps
=
useMemo
(()
=>
3
,
[])
const
steps
=
useMemo
(()
=>
2
,
[])
return
(
return
(
<
div
className=
{
classes
.
pageContent
}
>
<
div
className=
{
classes
.
pageContent
}
>
...
@@ -66,9 +63,6 @@ const Simulation = (props: Props) => {
...
@@ -66,9 +63,6 @@ const Simulation = (props: Props) => {
<
Step
>
<
Step
>
<
StepLabel
>
Dados pessoais
</
StepLabel
>
<
StepLabel
>
Dados pessoais
</
StepLabel
>
</
Step
>
</
Step
>
<
Step
>
<
StepLabel
>
Código de verificação
</
StepLabel
>
</
Step
>
</
Stepper
>
</
Stepper
>
<
Button
size=
"large"
onClick=
{
handleNext
}
disabled=
{
!
canGoForward
}
className=
{
classes
.
stepperBtn
}
>
<
Button
size=
"large"
onClick=
{
handleNext
}
disabled=
{
!
canGoForward
}
className=
{
classes
.
stepperBtn
}
>
{
activeStep
===
steps
-
1
?
(
{
activeStep
===
steps
-
1
?
(
...
...
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/FirstAccessDialog/CreatePassword/CreatePassword.tsx
0 → 100644
View file @
06b6c363
import
React
from
'react'
import
TextFieldWithIcon
from
'@agiliza/components/atoms/TextFieldWithIcon'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
styles
from
'./styles'
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
interface
Props
extends
ExtendedProps
{
password
:
string
confirmPassword
:
string
onChange
(
type
:
'password'
|
'confirmPassword'
):
(
value
:
string
)
=>
void
}
const
CreatePassword
=
(
props
:
Props
)
=>
{
const
{
classes
,
password
,
confirmPassword
,
onChange
}
=
props
return
(
<
div
className=
{
classes
.
dialogContent
}
>
<
TextFieldWithIcon
label=
"Senha"
value=
{
password
}
onChange=
{
(
evt
)
=>
onChange
(
'password'
)(
evt
.
target
.
value
)
}
type=
"password"
/>
<
TextFieldWithIcon
label=
"Confirmar senha"
value=
{
confirmPassword
}
onChange=
{
(
evt
)
=>
onChange
(
'confirmPassword'
)(
evt
.
target
.
value
)
}
type=
"password"
/>
</
div
>
)
}
export
default
withStyles
(
styles
)(
CreatePassword
)
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/FirstAccessDialog/CreatePassword/index.ts
0 → 100644
View file @
06b6c363
export
{
default
}
from
'./CreatePassword'
export
*
from
'./CreatePassword'
cli/web/src/views/SimulationCreditLines/pages/Simulation/
VerificationCode
/styles.ts
→
cli/web/src/views/SimulationCreditLines/pages/Simulation/
UserForm/FirstAccessDialog/CreatePassword
/styles.ts
View file @
06b6c363
...
@@ -7,5 +7,5 @@ import sharedStyles from '../styles'
...
@@ -7,5 +7,5 @@ import sharedStyles from '../styles'
export
default
(
theme
:
Theme
)
=>
export
default
(
theme
:
Theme
)
=>
createStyles
({
createStyles
({
...
sharedStyles
(
theme
),
...
sharedStyles
(
theme
),
codeField
:
{
marginTop
:
theme
.
spacing
(
5
)
},
title
:
{
marginBottom
:
theme
.
spacing
(
2
)
},
})
})
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/FirstAccessDialog/FirstAccessDialog.tsx
0 → 100644
View file @
06b6c363
import
React
,
{
useEffect
,
useMemo
,
useState
}
from
'react'
import
ButtonWithProgress
from
'@agiliza/components/atoms/ButtonWithProgress'
import
FirstAccessTemplate
,
{
initState
}
from
'@agiliza/components/templates/FirstAccess'
import
{
useFormState
}
from
'@agiliza/utils/hooks/state'
import
{
values
}
from
'@agiliza/utils/method'
import
{
isValidCPF
}
from
'@agiliza/utils/validators'
import
{
Button
,
Dialog
,
DialogActions
,
DialogContent
,
DialogProps
,
DialogTitle
,
MobileStepper
}
from
'@material-ui/core'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
{
KeyboardArrowLeft
as
KeyboardArrowLeftIcon
,
KeyboardArrowRight
as
KeyboardArrowRightIcon
}
from
'@material-ui/icons'
import
{
connected
,
ConnectedProps
}
from
'./connect'
import
CreatePassword
from
'./CreatePassword'
import
styles
from
'./styles'
import
VerifyCode
from
'./VerifyCode'
import
VerifyCPF
from
'./VerifyCPF'
type
ExtendedProps
=
Pick
<
DialogProps
,
'open'
>
&
WithStyles
<
typeof
styles
>
&
ConnectedProps
interface
Props
extends
ExtendedProps
{
onClose
:
()
=>
void
}
const
FirstAccessDialog
=
(
props
:
Props
)
=>
{
const
{
classes
,
open
,
onClose
,
context
,
fetching
,
sendingCode
}
=
props
const
{
state
,
actions
}
=
useFormState
(
'firstAccessForm'
,
initState
)
const
[
code
,
setCode
]
=
useState
(
''
)
const
[
password
,
setPassword
]
=
useState
(
''
)
const
[
confirmPassword
,
setConfirmPassword
]
=
useState
(
''
)
useEffect
(()
=>
{
if
(
!
context
.
states
.
length
)
props
.
getContext
()
},
[])
const
{
states
,
cities
}
=
context
const
[
activeStep
,
setActiveStep
]
=
useState
(
0
)
const
{
cpf
,
email
}
=
state
const
handleNext
=
()
=>
{
switch
(
activeStep
)
{
case
0
:
props
.
verifyCPF
({
cpf
,
onSuccess
:
()
=>
setActiveStep
((
prevActiveStep
)
=>
prevActiveStep
+
1
),
})
break
case
1
:
props
.
createCustomer
({
...
state
,
onSuccess
:
()
=>
{
props
.
sendCode
({
cpf
,
email
,
onSuccess
:
()
=>
setActiveStep
((
prevActiveStep
)
=>
prevActiveStep
+
1
)
})
},
})
break
case
2
:
props
.
verifyCode
({
cpf
,
code
,
onSuccess
:
()
=>
setActiveStep
((
prevActiveStep
)
=>
prevActiveStep
+
1
)
})
break
case
3
:
props
.
createPassword
({
cpf
,
code
,
password
,
onSuccess
:
()
=>
{
props
.
login
({
username
:
cpf
,
password
,
onSuccess
:
onClose
})
},
})
break
default
:
setActiveStep
((
prevActiveStep
)
=>
prevActiveStep
+
1
)
}
}
const
handleBack
=
()
=>
{
setActiveStep
((
prevActiveStep
)
=>
prevActiveStep
-
1
)
}
const
steps
=
useMemo
(()
=>
4
,
[])
const
canGoForward
=
useMemo
(()
=>
{
switch
(
activeStep
)
{
case
0
:
return
isValidCPF
(
state
.
cpf
)
case
1
:
return
values
(
state
).
every
((
st
)
=>
!!
st
)
case
2
:
return
!!
code
case
3
:
return
password
&&
confirmPassword
&&
password
===
confirmPassword
}
},
[
state
,
code
,
activeStep
,
confirmPassword
,
password
])
const
renderStep
=
(
step
:
number
)
=>
{
switch
(
step
)
{
case
0
:
return
<
VerifyCPF
cpf=
{
state
.
cpf
}
onChange=
{
(
cpf
)
=>
actions
.
update
({
cpf
})
}
/>
case
1
:
return
<
FirstAccessTemplate
state=
{
state
}
actions=
{
actions
}
states=
{
states
}
cities=
{
cities
}
/>
case
2
:
return
<
VerifyCode
code=
{
code
}
onChange=
{
(
value
)
=>
setCode
(
value
)
}
onResendCode=
{
()
=>
props
.
sendCode
({
cpf
,
email
})
}
/>
case
3
:
return
(
<
CreatePassword
password=
{
password
}
confirmPassword=
{
confirmPassword
}
onChange=
{
(
type
)
=>
(
value
)
=>
{
if
(
type
===
'password'
)
setPassword
(
value
)
if
(
type
===
'confirmPassword'
)
setConfirmPassword
(
value
)
}
}
/>
)
}
}
return
(
<
Dialog
onClose=
{
onClose
}
aria
-
labelledby=
"simple-dialog-title"
open=
{
open
}
PaperProps=
{
{
className
:
classes
.
dialog
}
}
>
<
DialogTitle
>
Primeiro acesso
</
DialogTitle
>
<
DialogContent
>
{
renderStep
(
activeStep
)
}
</
DialogContent
>
<
DialogActions
>
<
MobileStepper
variant=
"dots"
steps=
{
steps
}
position=
"static"
activeStep=
{
activeStep
}
className=
{
classes
.
stepper
}
nextButton=
{
<
ButtonWithProgress
fetching=
{
fetching
||
sendingCode
}
size=
"small"
variant=
"text"
onClick=
{
handleNext
}
disabled=
{
!
canGoForward
||
activeStep
===
steps
}
>
{
activeStep
===
steps
-
1
?
(
'Finalizar'
)
:
(
<>
Próximo
<
KeyboardArrowRightIcon
/>
</>
)
}
</
ButtonWithProgress
>
}
backButton=
{
<
Button
size=
"small"
onClick=
{
handleBack
}
disabled=
{
activeStep
===
0
}
>
<
KeyboardArrowLeftIcon
/>
Anterior
</
Button
>
}
/>
</
DialogActions
>
</
Dialog
>
)
}
export
default
connected
(
withStyles
(
styles
)(
FirstAccessDialog
))
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/FirstAccessDialog/VerifyCPF/VerifyCPF.tsx
0 → 100644
View file @
06b6c363
import
React
from
'react'
import
{
maskCPFCNPJ
}
from
'@agiliza/utils/masks'
import
{
TextField
,
Typography
}
from
'@material-ui/core'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
styles
from
'./styles'
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
interface
Props
extends
ExtendedProps
{
cpf
:
string
onChange
:
(
value
:
string
)
=>
void
}
const
VerifyCPF
=
(
props
:
Props
)
=>
{
const
{
classes
,
cpf
,
onChange
}
=
props
return
(
<
div
className=
{
classes
.
dialogContent
}
>
<
Typography
className=
{
classes
.
title
}
>
Informe o seu CPF
</
Typography
>
<
TextField
variant=
"outlined"
// label="CPF"
value=
{
maskCPFCNPJ
(
cpf
)
}
onChange=
{
(
evt
)
=>
onChange
(
evt
.
target
.
value
)
}
inputProps=
{
{
maxLength
:
14
}
}
/>
</
div
>
)
}
export
default
withStyles
(
styles
)(
VerifyCPF
)
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/FirstAccessDialog/VerifyCPF/index.ts
0 → 100644
View file @
06b6c363
export
{
default
}
from
'./VerifyCPF'
export
*
from
'./VerifyCPF'
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/FirstAccessDialog/VerifyCPF/styles.ts
0 → 100644
View file @
06b6c363
import
{
Theme
}
from
'@material-ui/core/styles'
import
{
createStyles
}
from
'@material-ui/styles'
import
sharedStyles
from
'../styles'
// eslint-disable-next-line
export
default
(
theme
:
Theme
)
=>
createStyles
({
...
sharedStyles
(
theme
),
title
:
{
marginBottom
:
theme
.
spacing
(
2
)
},
})
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/FirstAccessDialog/VerifyCode/VerifyCode.tsx
0 → 100644
View file @
06b6c363
import
React
from
'react'
import
{
extractNumbers
}
from
'@agiliza/utils/method'
import
{
Button
,
TextField
,
Typography
}
from
'@material-ui/core'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
styles
from
'./styles'
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
interface
Props
extends
ExtendedProps
{
code
:
string
onChange
:
(
value
:
string
)
=>
void
onResendCode
:
()
=>
void
}
const
VerifyCode
=
(
props
:
Props
)
=>
{
const
{
classes
,
code
,
onChange
}
=
props
return
(
<
div
className=
{
classes
.
dialogContent
}
>
<
Typography
className=
{
classes
.
title
}
>
Foi enviado um código de verificação por email.
</
Typography
>
<
TextField
variant=
"outlined"
value=
{
code
}
onChange=
{
(
evt
)
=>
onChange
(
extractNumbers
(
evt
.
target
.
value
))
}
inputProps=
{
{
maxLength
:
14
}
}
/>
<
div
style=
{
{
display
:
'flex'
,
width
:
'100%'
,
justifyContent
:
'flex-end'
}
}
onClick=
{
props
.
onResendCode
}
>
<
Button
>
Re-enviar código
</
Button
>
</
div
>
</
div
>
)
}
export
default
withStyles
(
styles
)(
VerifyCode
)
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/FirstAccessDialog/VerifyCode/index.ts
0 → 100644
View file @
06b6c363
export
{
default
}
from
'./VerifyCode'
export
*
from
'./VerifyCode'
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/FirstAccessDialog/VerifyCode/styles.ts
0 → 100644
View file @
06b6c363
import
{
Theme
}
from
'@material-ui/core/styles'
import
{
createStyles
}
from
'@material-ui/styles'
import
sharedStyles
from
'../styles'
// eslint-disable-next-line
export
default
(
theme
:
Theme
)
=>
createStyles
({
...
sharedStyles
(
theme
),
title
:
{
marginBottom
:
theme
.
spacing
(
2
)
},
})
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/FirstAccessDialog/connect.ts
0 → 100644
View file @
06b6c363
import
{
connect
}
from
'react-redux'
import
{
bindActionCreators
,
Dispatch
}
from
'redux'
import
{
AuthenticationContext
}
from
'@agiliza/api/domain'
import
{
StoreState
}
from
'@agiliza/redux'
import
*
as
entAuthentication
from
'@agiliza/redux/entities/authentication'
import
*
as
uiLogin
from
'@agiliza/redux/ui/login'
import
*
as
ucAuthentication
from
'@agiliza/redux/useCases/authentication'
export
interface
ConnectedProps
{
fetching
:
boolean
sendingCode
:
boolean
context
:
AuthenticationContext
getContext
:
typeof
ucAuthentication
.
actions
.
getContext
verifyCPF
:
typeof
ucAuthentication
.
actions
.
verifyCPF
createCustomer
:
typeof
ucAuthentication
.
actions
.
createCustomer
sendCode
:
typeof
ucAuthentication
.
actions
.
sendCode
verifyCode
:
typeof
ucAuthentication
.
actions
.
verifyCode
createPassword
:
typeof
ucAuthentication
.
actions
.
createPassword
login
:
typeof
uiLogin
.
actions
.
login
}
type
StateProps
=
Pick
<
ConnectedProps
,
'fetching'
|
'context'
|
'sendingCode'
>
type
DispatchProps
=
Pick
<
ConnectedProps
,
'getContext'
|
'verifyCPF'
|
'createCustomer'
|
'verifyCode'
|
'createPassword'
|
'sendCode'
|
'login'
>
const
mapStateToProps
=
(
state
:
StoreState
):
StateProps
=>
({
fetching
:
ucAuthentication
.
selectors
.
isFetching
(
state
.
useCases
.
authentication
),
context
:
entAuthentication
.
selectors
.
getContextEntities
(
state
.
entities
.
authentication
),
sendingCode
:
ucAuthentication
.
selectors
.
isSendingCode
(
state
.
useCases
.
authentication
),
})
const
mapDispatchToProps
=
(
dispatch
:
Dispatch
):
DispatchProps
=>
bindActionCreators
(
{
getContext
:
ucAuthentication
.
actions
.
getContext
,
verifyCPF
:
ucAuthentication
.
actions
.
verifyCPF
,
createCustomer
:
ucAuthentication
.
actions
.
createCustomer
,
sendCode
:
ucAuthentication
.
actions
.
sendCode
,
verifyCode
:
ucAuthentication
.
actions
.
verifyCode
,
createPassword
:
ucAuthentication
.
actions
.
createPassword
,
login
:
uiLogin
.
actions
.
login
,
},
dispatch
)
export
const
connected
=
connect
(
mapStateToProps
,
mapDispatchToProps
)
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/FirstAccessDialog/index.ts
0 → 100644
View file @
06b6c363
export
{
default
}
from
'./FirstAccessDialog'
export
*
from
'./FirstAccessDialog'
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/FirstAccessDialog/styles.ts
0 → 100644
View file @
06b6c363
import
{
Theme
}
from
'@material-ui/core/styles'
import
{
createStyles
}
from
'@material-ui/styles'
import
sharedStyles
from
'../styles'
// eslint-disable-next-line
export
default
(
theme
:
Theme
)
=>
createStyles
({
...
sharedStyles
(
theme
),
gridContainer
:
{
marginBottom
:
theme
.
spacing
(
1
)
},
dialog
:
{
height
:
'60%'
,
width
:
'65%'
},
gridHeaderText
:
{
fontWeight
:
'bold'
},
stepper
:
{
...
sharedStyles
(
theme
).
stepper
,
background
:
'white'
},
dialogContent
:
{
height
:
'100%'
,
width
:
'100%'
,
display
:
'flex'
,
flexDirection
:
'column'
,
alignItems
:
'center'
,
justifyContent
:
'center'
,
'& .MuiTextField-root'
:
{
marginBottom
:
theme
.
spacing
(
2
),
},
},
})
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/UserForm.tsx
View file @
06b6c363
import
React
,
{
useEffect
,
useState
}
from
'react'
import
React
,
{
useEffect
,
useState
}
from
'react'
import
{
formatPhone
}
from
'@agiliza/utils/formatters'
import
ButtonWithProgress
from
'@agiliza/components/atoms/ButtonWithProgress'
import
{
import
LoginTemplate
from
'@agiliza/components/templates/Login'
getErrorProps
,
import
{
formatCPF
}
from
'@agiliza/utils/formatters'
invalidState
,
import
{
extractNumbers
}
from
'@agiliza/utils/method'
useErrorValidator
,
import
{
Button
,
TextFieldProps
,
Typography
}
from
'@material-ui/core'
Validators
,
validState
}
from
'@agiliza/utils/hooks/errorValidation'
import
{
isValidEmail
,
isValidPhone
}
from
'@agiliza/utils/validators'
import
{
TextField
,
TextFieldProps
}
from
'@material-ui/core'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
{
connected
,
ConnectedProps
}
from
'./connect'
import
FirstAccessDialog
from
'./FirstAccessDialog'
import
styles
from
'./styles'
import
styles
from
'./styles'
interface
UserFormFieldProps
extends
Pick
<
TextFieldProps
,
'label'
|
'value'
|
'onChange'
|
'error'
|
'helperText'
|
'inputProps'
>
{}
//
interface UserFormFieldProps extends Pick<TextFieldProps, 'label' | 'value' | 'onChange' | 'error' | 'helperText' | 'inputProps'> {}
const
UserFormField
=
({
helperText
,
...
props
}:
UserFormFieldProps
)
=>
<
TextField
fullWidth
margin=
"normal"
variant=
"outlined"
{
...
props
}
/>
//
const UserFormField = ({ helperText, ...props }: UserFormFieldProps) => <TextField fullWidth margin="normal" variant="outlined" {...props} />
interface
State
{
interface
State
{
name
:
string
username
:
string
phoneNumber
:
string
password
:
string
email
:
string
}
}
const
validators
:
Validators
<
Partial
<
State
>>
=
{
//
const validators: Validators<Partial<State>> = {
phoneNumber
:
(
vl
)
=>
(
isValidPhone
(
vl
)
?
validState
(
vl
)
:
invalidState
(
vl
,
''
)),
//
phoneNumber: (vl) => (isValidPhone(vl) ? validState(vl) : invalidState(vl, '')),
email
:
(
vl
)
=>
(
isValidEmail
(
vl
)
?
validState
(
vl
)
:
invalidState
(
vl
,
''
)),
//
email: (vl) => (isValidEmail(vl) ? validState(vl) : invalidState(vl, '')),
}
//
}
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
&
ConnectedProps
interface
Props
extends
ExtendedProps
{
interface
Props
extends
ExtendedProps
{
onChangeCanGoForward
:
(
vl
:
boolean
)
=>
void
onChangeCanGoForward
:
(
vl
:
boolean
)
=>
void
}
}
const
UserForm
=
(
props
:
Props
)
=>
{
const
UserForm
=
(
props
:
Props
)
=>
{
const
{
classes
,
onChangeCanGoForward
}
=
props
const
{
classes
,
fetching
,
onChangeCanGoForward
,
customer
}
=
props
const
[
state
,
setState
]
=
useState
<
State
>
({
email
:
''
,
phoneNumber
:
''
,
name
:
''
})
const
[
state
,
setState
]
=
useState
<
State
>
({
username
:
''
,
password
:
''
})
const
{
name
,
phoneNumber
,
email
}
=
state
const
{
username
,
password
}
=
state
const
[
open
,
setOpen
]
=
useState
(
false
)
const
{
errorState
,
validState
:
isValidState
,
actions
}
=
useErrorValidator
({
email
:
''
,
phoneNumber
:
''
,
name
:
''
},
validators
)
// const { errorState, validState: isValidState, actions } = useErrorValidator({ username: '', password: '' }
)
useEffect
(()
=>
{
useEffect
(()
=>
{
onChangeCanGoForward
(
isValidStat
e
)
onChangeCanGoForward
(
fals
e
)
},
[])
},
[])
useEffect
(()
=>
{
//
useEffect(() => {
onChangeCanGoForward
(
isValidState
)
//
onChangeCanGoForward(isValidState)
},
[
isValidState
])
//
}, [isValidState])
const
handleChange
=
const
handleChange
=
(
key
:
keyof
State
):
TextFieldProps
[
'onChange'
]
=>
(
key
:
keyof
State
):
TextFieldProps
[
'onChange'
]
=>
(
evt
)
=>
{
(
evt
)
=>
{
setState
({
...
state
,
[
key
]:
evt
.
target
.
value
})
setState
({
...
state
,
[
key
]:
evt
.
target
.
value
})
actions
.
validate
({
[
key
]:
evt
.
target
.
value
})
//
actions.validate({ [key]: evt.target.value })
}
}
return
(
return
(
<
div
className=
{
classes
.
contentContainer
}
>
<
div
className=
{
classes
.
contentContainer
}
>
<
div
className=
{
classes
.
content
}
>
<
div
className=
{
classes
.
content
}
>
<
UserFormField
label=
"Nome"
value=
{
name
}
onChange=
{
handleChange
(
'name'
)
}
{
...
getErrorProps
(
errorState
.
name
)}
/>
<
Typography
>
Identifique-se
</
Typography
>
<
LoginTemplate
username=
{
formatCPF
(
username
)
}
password=
{
password
}
onChange=
{
handleChange
}
/>
<
ButtonWithProgress
className=
{
classes
.
btn
}
fetching=
{
fetching
}
disabled=
{
!
username
||
!!
customer
}
color=
"secondary"
onClick=
{
()
=>
props
.
login
({
username
:
extractNumbers
(
username
),
password
,
onSuccess
:
()
=>
{
onChangeCanGoForward
(
true
)
},
})
}
>
{
!
customer
?
'Identificar'
:
'Identificado'
}
</
ButtonWithProgress
>
<
Button
variant=
"contained"
className=
{
classes
.
btn
}
color=
"secondary"
onClick=
{
()
=>
setOpen
(
true
)
}
disabled=
{
!!
customer
}
>
Primeiro aceeso
</
Button
>
{
/* <UserFormField label="Nome" value={name} onChange={handleChange('name')} {...getErrorProps(errorState.name)} />
<UserFormField
<UserFormField
label="Número de celular"
label="Número de celular"
value={formatPhone(phoneNumber)}
value={formatPhone(phoneNumber)}
...
@@ -68,10 +87,11 @@ const UserForm = (props: Props) => {
...
@@ -68,10 +87,11 @@ const UserForm = (props: Props) => {
inputProps={{ maxLength: 15 }}
inputProps={{ maxLength: 15 }}
{...getErrorProps(errorState.phoneNumber)}
{...getErrorProps(errorState.phoneNumber)}
/>
/>
<
UserFormField
label=
"Email"
value=
{
email
}
onChange=
{
handleChange
(
'email'
)
}
{
...
getErrorProps
(
errorState
.
email
)}
/>
<UserFormField label="Email" value={email} onChange={handleChange('email')} {...getErrorProps(errorState.email)} />
*/
}
</
div
>
</
div
>
<
FirstAccessDialog
open=
{
open
}
onClose=
{
()
=>
setOpen
(
false
)
}
/>
</
div
>
</
div
>
)
)
}
}
export
default
withStyles
(
styles
)(
UserForm
)
export
default
connected
(
withStyles
(
styles
)(
UserForm
)
)
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/connect.ts
0 → 100644
View file @
06b6c363
import
{
connect
}
from
'react-redux'
import
{
bindActionCreators
,
Dispatch
}
from
'redux'
import
{
Customer
}
from
'@agiliza/api/domain'
import
{
StoreState
}
from
'@agiliza/redux'
import
*
as
session
from
'@agiliza/redux/session'
import
*
as
uiLogin
from
'@agiliza/redux/ui/login'
export
interface
ConnectedProps
{
fetching
:
boolean
login
:
typeof
uiLogin
.
actions
.
login
customer
?:
Customer
}
type
StateProps
=
Pick
<
ConnectedProps
,
'fetching'
|
'customer'
>
type
DispatchProps
=
Pick
<
ConnectedProps
,
'login'
>
const
mapStateToProps
=
(
state
:
StoreState
):
StateProps
=>
({
fetching
:
uiLogin
.
selectors
.
isFetching
(
state
.
ui
.
login
),
customer
:
session
.
selectors
.
getCustomer
(
state
.
session
),
})
const
mapDispatchToProps
=
(
dispatch
:
Dispatch
):
DispatchProps
=>
bindActionCreators
(
{
login
:
uiLogin
.
actions
.
login
,
},
dispatch
)
export
const
connected
=
connect
(
mapStateToProps
,
mapDispatchToProps
)
cli/web/src/views/SimulationCreditLines/pages/Simulation/UserForm/styles.ts
View file @
06b6c363
...
@@ -7,6 +7,8 @@ import sharedStyles from '../styles'
...
@@ -7,6 +7,8 @@ import sharedStyles from '../styles'
export
default
(
theme
:
Theme
)
=>
export
default
(
theme
:
Theme
)
=>
createStyles
({
createStyles
({
...
sharedStyles
(
theme
),
...
sharedStyles
(
theme
),
content
:
{
...
sharedStyles
(
theme
).
content
,
width
:
'15%'
},
gridContainer
:
{},
gridContainer
:
{},
gridItem
:
{
whiteSpace
:
'nowrap'
},
gridItem
:
{
whiteSpace
:
'nowrap'
},
btn
:
{
width
:
'100%'
,
marginBottom
:
theme
.
spacing
(
1
)
},
})
})
cli/web/src/views/SimulationCreditLines/pages/Simulation/VerificationCode/VerificationCode.tsx
deleted
100644 → 0
View file @
533c4f22
import
React
,
{
useEffect
,
useState
}
from
'react'
import
{
extractNumbers
}
from
'@agiliza/utils/extractors'
import
{
TextField
,
TextFieldProps
,
Typography
}
from
'@material-ui/core'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
styles
from
'./styles'
type
ExtendedProps
=
WithStyles
<
typeof
styles
>
interface
Props
extends
ExtendedProps
{
onChangeCanGoForward
:
(
vl
:
boolean
)
=>
void
}
const
VerificationCode
=
(
props
:
Props
)
=>
{
const
{
classes
,
onChangeCanGoForward
}
=
props
const
[
code
,
setCode
]
=
useState
(
''
)
useEffect
(()
=>
{
onChangeCanGoForward
(
code
.
length
===
6
)
},
[
code
])
const
handleChange
:
TextFieldProps
[
'onChange'
]
=
(
evt
)
=>
{
setCode
(
extractNumbers
(
evt
.
target
.
value
))
}
return
(
<
div
className=
{
classes
.
contentContainer
}
>
<
div
className=
{
classes
.
content
}
>
<
Typography
variant=
"h5"
>
Foi enviado um código de verificação por email.
</
Typography
>
<
TextField
label=
"Código de verificação"
value=
{
code
}
onChange=
{
handleChange
}
variant=
"outlined"
className=
{
classes
.
codeField
}
inputProps=
{
{
maxLength
:
6
}
}
/>
</
div
>
</
div
>
)
}
export
default
withStyles
(
styles
)(
VerificationCode
)
cli/web/src/views/SimulationCreditLines/pages/Simulation/VerificationCode/index.ts
deleted
100644 → 0
View file @
533c4f22
export
{
default
}
from
'./VerificationCode'
export
*
from
'./VerificationCode'
cli/web/src/views/SimulationCreditLines/pages/router.tsx
View file @
06b6c363
import
React
,
{
lazy
,
Suspense
}
from
'react'
import
React
,
{
lazy
,
Suspense
}
from
'react'
import
{
Redirect
,
Route
,
RouteComponentProps
,
Switch
}
from
'react-router'
import
{
Redirect
,
Route
,
RouteComponentProps
,
Switch
}
from
'react-router'
import
NotFound
from
'@agiliza/components/templates/NotFound'
import
{
CircularProgress
}
from
'@material-ui/core'
import
{
CircularProgress
}
from
'@material-ui/core'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
import
{
withStyles
,
WithStyles
}
from
'@material-ui/core/styles'
...
@@ -25,14 +24,15 @@ const CreditLinesRouter = (props: Props) => {
...
@@ -25,14 +24,15 @@ const CreditLinesRouter = (props: Props) => {
<
div
className=
{
classes
.
pageContent
}
>
<
div
className=
{
classes
.
pageContent
}
>
<
Suspense
fallback=
{
<
CircularProgress
className=
{
classes
.
circularProgress
}
/>
}
>
<
Suspense
fallback=
{
<
CircularProgress
className=
{
classes
.
circularProgress
}
/>
}
>
<
Switch
>
<
Switch
>
<
Route
exact
path=
{
match
.
path
+
CREDIT_LINES_PATHS
.
creditLinesList
}
render=
{
(
rProps
)
=>
<
CreditLinesList
fetching=
{
false
}
{
...
rProps
}
/>
}
/>
<
Route
exact
path=
{
match
.
path
+
CREDIT_LINES_PATHS
.
creditLinesList
}
render=
{
(
rProps
)
=>
<
CreditLinesList
{
...
rProps
}
/>
}
/>
<
Route
<
Route
exact
exact
path=
{
match
.
path
+
CREDIT_LINES_PATHS
.
simulation
}
path=
{
match
.
path
+
CREDIT_LINES_PATHS
.
simulation
}
render=
{
(
rProps
)
=>
{
render=
{
(
rProps
)
=>
{
const
{
location
}
=
rProps
as
RouteComponentProps
<
any
,
any
,
{
id
:
string
}
>
return
<
Simulation
{
...
rProps
}
/>
if
(
location
.
state
?.
id
)
return
<
Simulation
{
...
rProps
}
/>
// const
{
location
}
=
rProps
as
RouteComponentProps
<
any
,
any
,
{
id
:
string
}
>
else
return
<
NotFound
{
...
rProps
}
/>
// if (location.state?.id) return <Simulation
{...
rProps
}
/
>
// else return <NotFound
{...
rProps
}
/
>
}
}
}
}
/>
/>
<
Redirect
from=
{
match
.
path
}
to=
{
match
.
path
+
CREDIT_LINES_PATHS
.
creditLinesList
}
/>
<
Redirect
from=
{
match
.
path
}
to=
{
match
.
path
+
CREDIT_LINES_PATHS
.
creditLinesList
}
/>
...
...
cli/web/src/views/index.tsx
View file @
06b6c363
...
@@ -6,18 +6,12 @@ import { bindActionCreators, Dispatch } from 'redux'
...
@@ -6,18 +6,12 @@ import { bindActionCreators, Dispatch } from 'redux'
import
AuthRoute
from
'@agiliza/components/atoms/AuthRoute'
import
AuthRoute
from
'@agiliza/components/atoms/AuthRoute'
import
CircularProgress
from
'@agiliza/components/molecules/CircularProgress'
import
CircularProgress
from
'@agiliza/components/molecules/CircularProgress'
import
{
ConfigService
}
from
'@agiliza/curio/SessionManager'
import
{
StoreState
}
from
'@agiliza/redux'
import
{
StoreState
}
from
'@agiliza/redux'
import
{
actions
as
sessionActions
}
from
'@agiliza/redux/session'
import
{
isAuthenticated
,
isAuthenticating
,
isInitializing
}
from
'@agiliza/redux/session/selectors'
import
{
getServiceInfo
,
isAuthenticated
,
isAuthenticating
,
isInitializing
}
from
'@agiliza/redux/session/selectors'
import
{
actions
as
drawerActions
}
from
'@agiliza/redux/ui/drawer'
import
{
actions
as
drawerActions
}
from
'@agiliza/redux/ui/drawer'
import
{
isDrawerOpen
}
from
'@agiliza/redux/ui/drawer/selectors'
import
{
isDrawerOpen
}
from
'@agiliza/redux/ui/drawer/selectors'
import
{
getError
}
from
'@agiliza/redux/ui/error/selectors'
import
{
getError
}
from
'@agiliza/redux/ui/error/selectors'
import
{
actions
as
loginActions
}
from
'@agiliza/redux/ui/login'
const
Login
=
lazy
(()
=>
import
(
'./Login'
))
const
Login
=
lazy
(()
=>
import
(
'./Login'
))
const
Main
=
lazy
(()
=>
import
(
'./Main'
))
const
Main
=
lazy
(()
=>
import
(
'./Main'
))
...
@@ -28,15 +22,14 @@ interface Props {
...
@@ -28,15 +22,14 @@ interface Props {
error
:
string
error
:
string
authenticated
:
boolean
authenticated
:
boolean
authenticating
:
boolean
authenticating
:
boolean
initialize
:
typeof
sessionActions
.
initialize
connect
:
typeof
loginActions
.
connect
serviceInfo
?:
ConfigService
}
}
const
Views
=
(
props
:
Props
)
=>
{
const
Views
=
(
props
:
Props
)
=>
{
const
{
authenticating
,
serviceInfo
,
initialize
}
=
props
const
{
authenticating
}
=
props
useEffect
(()
=>
{
useEffect
(()
=>
{
initialize
()
props
.
connect
()
},
[])
},
[])
if
(
authenticating
)
return
<
CircularProgress
root
/>
if
(
authenticating
)
return
<
CircularProgress
root
/>
...
@@ -45,7 +38,7 @@ const Views = (props: Props) => {
...
@@ -45,7 +38,7 @@ const Views = (props: Props) => {
<
Router
history=
{
history
}
>
<
Router
history=
{
history
}
>
<
Suspense
fallback=
{
<
CircularProgress
/>
}
>
<
Suspense
fallback=
{
<
CircularProgress
/>
}
>
<
Switch
>
<
Switch
>
<
Route
path=
"/login"
render=
{
(
renderProps
)
=>
<
Login
{
...
renderProps
}
service=
{
serviceInfo
}
/>
}
/>
<
Route
path=
"/login"
render=
{
(
renderProps
)
=>
<
Login
{
...
renderProps
}
/>
}
/>
<
AuthRoute
path=
"/"
component=
{
Main
}
/>
<
AuthRoute
path=
"/"
component=
{
Main
}
/>
</
Switch
>
</
Switch
>
</
Suspense
>
</
Suspense
>
...
@@ -57,7 +50,6 @@ const mapStateToProps = (state: StoreState) => ({
...
@@ -57,7 +50,6 @@ const mapStateToProps = (state: StoreState) => ({
error
:
getError
(
state
.
ui
.
error
),
error
:
getError
(
state
.
ui
.
error
),
authenticated
:
isAuthenticated
(
state
.
session
),
authenticated
:
isAuthenticated
(
state
.
session
),
authenticating
:
isAuthenticating
(
state
.
session
)
||
isInitializing
(
state
.
session
),
authenticating
:
isAuthenticating
(
state
.
session
)
||
isInitializing
(
state
.
session
),
serviceInfo
:
getServiceInfo
(
state
.
session
),
drawerOpen
:
isDrawerOpen
(
state
.
ui
.
drawer
),
drawerOpen
:
isDrawerOpen
(
state
.
ui
.
drawer
),
})
})
...
@@ -65,7 +57,7 @@ const mapDispatchToProps = (dispatch: Dispatch) =>
...
@@ -65,7 +57,7 @@ const mapDispatchToProps = (dispatch: Dispatch) =>
bindActionCreators
(
bindActionCreators
(
{
{
toggleDrawer
:
drawerActions
.
toggleDrawer
,
toggleDrawer
:
drawerActions
.
toggleDrawer
,
initialize
:
sessionActions
.
initialize
,
connect
:
loginActions
.
connect
,
},
},
dispatch
dispatch
)
)
...
...
cli/web/tsconfig.json
View file @
06b6c363
...
@@ -57,5 +57,5 @@
...
@@ -57,5 +57,5 @@
"typeRoots"
:
[
"node_modules/@types"
,
"src/typings"
]
"typeRoots"
:
[
"node_modules/@types"
,
"src/typings"
]
},
},
"include"
:
[
"src"
],
"include"
:
[
"src"
],
"exclude"
:
[
"node_modules"
,
"dist"
,
"public"
]
"exclude"
:
[
"node_modules"
,
"dist"
]
}
}
cli/web/webpack.config.js
View file @
06b6c363
...
@@ -113,6 +113,7 @@ const makeCommonPlugins = (env) => [
...
@@ -113,6 +113,7 @@ const makeCommonPlugins = (env) => [
new
webpack
.
EnvironmentPlugin
({
new
webpack
.
EnvironmentPlugin
({
PUBLIC_PATH
:
'/'
,
PUBLIC_PATH
:
'/'
,
NODE_ENV
:
env
.
production
?
'production'
:
'development'
,
NODE_ENV
:
env
.
production
?
'production'
:
'development'
,
PRODUCTION
:
env
.
production
,
APP_TITLE
:
'Agiliza'
,
APP_TITLE
:
'Agiliza'
,
}),
}),
new
HtmlWebpackPlugin
({
new
HtmlWebpackPlugin
({
...
@@ -188,5 +189,8 @@ module.exports = (env) => {
...
@@ -188,5 +189,8 @@ module.exports = (env) => {
new
CssMinimizerPlugin
(),
new
CssMinimizerPlugin
(),
],
],
},
},
experiments
:
{
topLevelAwait
:
true
,
},
}
}
}
}
cli/web/yarn.lock
View file @
06b6c363
...
@@ -1264,6 +1264,11 @@
...
@@ -1264,6 +1264,11 @@
prop-types "^15.7.2"
prop-types "^15.7.2"
react-is "^16.8.0 || ^17.0.0"
react-is "^16.8.0 || ^17.0.0"
"@microcredito/client@^0.7.11":
version "0.7.11"
resolved "https://nexus.dev.evologica.com.br/repository/npm/@microcredito/client/-/client-0.7.11.tgz#6601c681c6452c71d18e82f9ddca8bddeedf44a7"
integrity sha1-ZgHGgcZFLHHRjoL53cqL3e7fRKc=
"@nodelib/fs.scandir@2.1.4":
"@nodelib/fs.scandir@2.1.4":
version "2.1.4"
version "2.1.4"
resolved "https://nexus.dev.evologica.com.br/repository/npm/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69"
resolved "https://nexus.dev.evologica.com.br/repository/npm/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment