diff options
author | jloup <jeanloup.jamet@gmail.com> | 2018-02-22 11:31:59 +0100 |
---|---|---|
committer | jloup <jeanloup.jamet@gmail.com> | 2018-02-22 11:31:59 +0100 |
commit | 2f91f20a8645339385ada602684f4957f20f4da4 (patch) | |
tree | a084cf293af15cc6ea6a1417edad51fcf0674947 /cmd/web/js | |
parent | 3602fbf8412d69900d793a963c8e774f487f5e45 (diff) | |
download | Front-2f91f20a8645339385ada602684f4957f20f4da4.tar.gz Front-2f91f20a8645339385ada602684f4957f20f4da4.tar.zst Front-2f91f20a8645339385ada602684f4957f20f4da4.zip |
Poloniex connection.
Diffstat (limited to 'cmd/web/js')
-rw-r--r-- | cmd/web/js/api.js | 11 | ||||
-rw-r--r-- | cmd/web/js/main.jsx | 41 | ||||
-rw-r--r-- | cmd/web/js/otp.jsx | 6 | ||||
-rw-r--r-- | cmd/web/js/poloniex.jsx | 176 | ||||
-rw-r--r-- | cmd/web/js/signin.jsx | 4 | ||||
-rw-r--r-- | cmd/web/js/signup.jsx | 4 |
6 files changed, 191 insertions, 51 deletions
diff --git a/cmd/web/js/api.js b/cmd/web/js/api.js index e2acd1d..5c19fdf 100644 --- a/cmd/web/js/api.js +++ b/cmd/web/js/api.js | |||
@@ -53,6 +53,17 @@ var ApiEndpoints = { | |||
53 | return '/market/' + params.name; | 53 | return '/market/' + params.name; |
54 | } | 54 | } |
55 | }, | 55 | }, |
56 | 'MARKET_BALANCE': { | ||
57 | 'type': 'GET', | ||
58 | 'auth': true, | ||
59 | 'parameters': [ | ||
60 | {'name': 'name', 'mandatory': true, 'inquery': false}, | ||
61 | {'name': 'currency', 'mandatory': true, 'inquery': true}, | ||
62 | ], | ||
63 | 'buildUrl': function(params) { | ||
64 | return '/market/' + params.name + '/balance'; | ||
65 | } | ||
66 | }, | ||
56 | 'UPDATE_MARKET': { | 67 | 'UPDATE_MARKET': { |
57 | 'type': 'POST', | 68 | 'type': 'POST', |
58 | 'auth': true, | 69 | 'auth': true, |
diff --git a/cmd/web/js/main.jsx b/cmd/web/js/main.jsx index eb53057..e5e505d 100644 --- a/cmd/web/js/main.jsx +++ b/cmd/web/js/main.jsx | |||
@@ -1,15 +1,17 @@ | |||
1 | var SignupForm = require('./signup.js').SignupForm; | 1 | var SignupForm = require('./signup.js').SignupForm; |
2 | var SigninForm = require('./signin.js').SigninForm; | 2 | var SigninForm = require('./signin.js').SigninForm; |
3 | var OtpEnrollForm = require('./otp.js').OtpEnrollForm; | 3 | var OtpEnrollForm = require('./otp.js').OtpEnrollForm; |
4 | var PoloniexForm = require('./poloniex.js').PoloniexForm; | 4 | var PoloniexController = require('./poloniex.js').PoloniexController; |
5 | var App = require('./app.js'); | 5 | var App = require('./app.js'); |
6 | var Api = require('./api.js').Api; | 6 | var Api = require('./api.js').Api; |
7 | var cookies = require('./cookies.js'); | 7 | var cookies = require('./cookies.js'); |
8 | 8 | ||
9 | var Logo = React.createClass({ | 9 | var Logo = React.createClass({ |
10 | render: function() { | 10 | render: function() { |
11 | return (<div id='logo'> | 11 | return (<div className='row'> |
12 | <a href='/'>Cryptoportfolio</a> | 12 | <div id='logo' className='offset-4 col-4'> |
13 | <a href='/'>Cryptoportfolio</a> | ||
14 | </div> | ||
13 | </div>); | 15 | </div>); |
14 | } | 16 | } |
15 | }); | 17 | }); |
@@ -49,21 +51,12 @@ App.page('/signout', true, function(context) { | |||
49 | }); | 51 | }); |
50 | 52 | ||
51 | App.page('/me', true, function(context) { | 53 | App.page('/me', true, function(context) { |
52 | Api.Call('MARKET', {'name': 'poloniex'}, function(err, status, data) { | 54 | App.mount( |
53 | if (err) { | 55 | <div> |
54 | console.error(err, data); | 56 | <Logo /> |
55 | return; | 57 | <PoloniexController/> |
56 | } | 58 | </div> |
57 | 59 | ); | |
58 | App.mount( | ||
59 | <div> | ||
60 | <Logo /> | ||
61 | <p>Poloniex</p> | ||
62 | <PoloniexForm apiKey={data.key} apiSecret={data.secret}/> | ||
63 | </div> | ||
64 | ); | ||
65 | |||
66 | }.bind(this)); | ||
67 | }); | 60 | }); |
68 | 61 | ||
69 | App.page('/otp/setup', true, function(context) { | 62 | App.page('/otp/setup', true, function(context) { |
diff --git a/cmd/web/js/otp.jsx b/cmd/web/js/otp.jsx index 2717d9f..a0ee5cc 100644 --- a/cmd/web/js/otp.jsx +++ b/cmd/web/js/otp.jsx | |||
@@ -53,12 +53,12 @@ module.exports.OtpEnrollForm = React.createClass({ | |||
53 | ); | 53 | ); |
54 | } | 54 | } |
55 | return ( | 55 | return ( |
56 | <div className='row otp-enroll justify-content-center'> | 56 | <div className='row otp-enroll'> |
57 | <div className='col-lg-offset-4 col-lg-4 col-md-offset-4 col-md-4 col-sm-offset-4 col-sm-4 col-xs-offset-1 col-xs-10'> | 57 | <div className='offset-4 col-4 col-xs-offset-1 col-xs-10 text-center'> |
58 | {qrCode} | 58 | {qrCode} |
59 | <div className='row justify-content-center'> | 59 | <div className='row justify-content-center'> |
60 | <form role='form' onSubmit={this.handleSubmit}> | 60 | <form role='form' onSubmit={this.handleSubmit}> |
61 | <input className='form-control' type='pass' placeholder='pass' onChange={this.handlePassChange} /> | 61 | <input className='form-control' type='pass' placeholder='code' onChange={this.handlePassChange} /> |
62 | <input className='form-control submit' type='submit' value='Validate' /> | 62 | <input className='form-control submit' type='submit' value='Validate' /> |
63 | <div className={cName} ref='message'>{this.state.msg}</div> | 63 | <div className={cName} ref='message'>{this.state.msg}</div> |
64 | </form> | 64 | </form> |
diff --git a/cmd/web/js/poloniex.jsx b/cmd/web/js/poloniex.jsx index 877198d..8b577b4 100644 --- a/cmd/web/js/poloniex.jsx +++ b/cmd/web/js/poloniex.jsx | |||
@@ -1,49 +1,185 @@ | |||
1 | var Api = require('./api.js').Api; | 1 | var Api = require('./api.js').Api; |
2 | var App = require('./app.js'); | ||
3 | var classNames = require('classnames'); | 2 | var classNames = require('classnames'); |
4 | 3 | ||
5 | module.exports.PoloniexForm = React.createClass({ | 4 | module.exports.PoloniexController = React.createClass({ |
6 | getInitialState: function() { | 5 | getInitialState: function() { |
7 | return {'hideMsg': true, 'msg': '', 'msgOk': false, 'apiSecret': this.props.apiSecret, 'apiKey': this.props.apiKey}; | 6 | return {'apiKey': '', 'apiSecret': '', 'flag': 'loading', 'valueCurrency': null, 'balanceValue': null, 'balance': null}; |
8 | }, | 7 | }, |
9 | handleSubmit: function(e) { | 8 | handleCredentialsChange: function(key, secret) { |
9 | this.setState({'apiKey': key, 'apiSecret': secret}); | ||
10 | }, | ||
11 | handleCredentialsSubmit: function() { | ||
12 | if (!this.state.apiKey || !this.state.apiSecret) { | ||
13 | return; | ||
14 | } | ||
10 | Api.Call('UPDATE_MARKET', {'key': this.state.apiKey, 'secret': this.state.apiSecret, 'name': 'poloniex'}, function(err, status, data) { | 15 | Api.Call('UPDATE_MARKET', {'key': this.state.apiKey, 'secret': this.state.apiSecret, 'name': 'poloniex'}, function(err, status, data) { |
11 | if (err) { | 16 | if (err) { |
12 | console.error(err, data); | 17 | console.error(err, data); |
13 | this.displayMessage(App.errorCodeToMessage(err.code), false); | ||
14 | return; | 18 | return; |
15 | } | 19 | } |
16 | 20 | ||
17 | this.displayMessage('OK', true); | 21 | this.setState({'flag': 'loading', 'valueCurrency': null, 'balanceValue': null, 'balance': null}); |
22 | this.loadBalance(); | ||
23 | }.bind(this)); | ||
24 | }, | ||
25 | loadBalance: function() { | ||
26 | Api.Call('MARKET_BALANCE', {'name': 'poloniex', 'currency': 'BTC'}, function(err, status, data) { | ||
27 | if (err) { | ||
28 | console.error(err, data); | ||
29 | if (err.code === 'invalid_market_credentials') { | ||
30 | this.setState({'flag': 'invalidCredentials', 'valueCurrency': null, 'balanceValue': null, 'balance': null}); | ||
31 | } | ||
32 | return; | ||
33 | } | ||
18 | 34 | ||
35 | this.setState({'flag': 'ok', 'valueCurrency': data.valueCurrency, 'balanceValue': data.value, 'balance': data.balance}); | ||
19 | }.bind(this)); | 36 | }.bind(this)); |
37 | }, | ||
38 | componentDidMount: function() { | ||
39 | Api.Call('MARKET', {'name': 'poloniex'}, function(err, status, data) { | ||
40 | if (err) { | ||
41 | console.error(err, data); | ||
42 | return; | ||
43 | } | ||
44 | |||
45 | var flag = this.state.flag; | ||
46 | if (!data.key || !data.secret) { | ||
47 | flag = 'emptyCredentials'; | ||
48 | } else { | ||
49 | this.loadBalance(); | ||
50 | } | ||
51 | |||
52 | this.setState({'apiKey': data.key, 'apiSecret': data.secret, 'flag': flag}); | ||
53 | }.bind(this)); | ||
54 | }, | ||
55 | render: function() { | ||
56 | var displayText = null; | ||
57 | switch (this.state.flag) { | ||
58 | case 'loading': | ||
59 | displayText = 'Loading data from poloniex...'; | ||
60 | break; | ||
61 | case 'invalidCredentials': | ||
62 | displayText = 'Invalid poloniex credentials'; | ||
63 | break; | ||
64 | case 'emptyCredentials': | ||
65 | displayText = 'Please provide poloniex credentials'; | ||
66 | break; | ||
67 | default: | ||
68 | displayText = null; | ||
69 | } | ||
70 | return ( | ||
71 | <div> | ||
72 | <PoloniexBalance balanceCurrency={this.state.valueCurrency} | ||
73 | balanceValue={this.state.balanceValue} | ||
74 | balance={this.state.balance} | ||
75 | displayText={displayText}/> | ||
76 | <PoloniexCredentialsForm onLoadCredentials={this.onLoadCredentials} | ||
77 | onCredentialsSubmit={this.handleCredentialsSubmit} | ||
78 | onCredentialsChange={this.handleCredentialsChange} | ||
79 | apiSecret={this.state.apiSecret} | ||
80 | apiKey={this.state.apiKey}/> | ||
81 | </div> | ||
82 | ); | ||
83 | } | ||
84 | }); | ||
85 | |||
86 | var PoloniexBalance = React.createClass({ | ||
87 | getInitialState: function() { | ||
88 | return {'hideMsg': true, 'msg': '', 'msgOk': false}; | ||
89 | }, | ||
90 | render: function() { | ||
91 | var dashboard = null; | ||
92 | |||
93 | if (this.props.balanceValue !== null) { | ||
94 | |||
95 | var balance = Object.keys(this.props.balance).map(function(currency) { | ||
96 | return <div key={currency}><i className={classNames('cc', currency)}></i> {this.props.balance[currency]}</div>; | ||
97 | }.bind(this)); | ||
98 | |||
99 | dashboard = ( | ||
100 | <div className='row'> | ||
101 | <div className='col-4 align-self-center h-100'> | ||
102 | <div> | ||
103 | {balance} | ||
104 | </div> | ||
105 | </div> | ||
106 | <div className='offset-1 col-7 h-100 align-self-center'> | ||
107 | <div className='text-center'> | ||
108 | Balance ({this.props.balanceCurrency}): <span>{this.props.balanceValue} <i className={classNames('cc', this.props.balanceCurrency)}></i></span> | ||
109 | </div> | ||
110 | </div> | ||
111 | </div> | ||
112 | ); | ||
113 | } else { | ||
114 | dashboard = ( | ||
115 | <div className='row'> | ||
116 | <div className='col-12 text-center'> | ||
117 | <span>{this.props.displayText}</span> | ||
118 | </div> | ||
119 | </div> | ||
120 | |||
121 | ); | ||
122 | } | ||
123 | |||
124 | return ( | ||
125 | <div className='row'> | ||
126 | <div className='box offset-2 col-8'> | ||
127 | <div className='row'> | ||
128 | <div className='col-4'>Portfolio</div> | ||
129 | </div> | ||
130 | <hr/> | ||
131 | {dashboard} | ||
132 | </div> | ||
133 | </div> | ||
134 | ); | ||
135 | } | ||
136 | }); | ||
137 | |||
138 | module.exports.PoloniexBalance = PoloniexBalance; | ||
139 | |||
140 | var PoloniexCredentialsForm = React.createClass({ | ||
141 | getInitialState: function() { | ||
142 | return {'hideMsg': true, 'msg': '', 'editMode': false, 'msgOk': false}; | ||
143 | }, | ||
144 | handleSubmit: function(e) { | ||
145 | this.props.onCredentialsSubmit(); | ||
146 | this.setState({'editMode': false}); | ||
20 | e.preventDefault(); | 147 | e.preventDefault(); |
21 | }, | 148 | }, |
22 | handleApiKeyChange: function(event) { | 149 | handleApiKeyChange: function(event) { |
23 | this.setState({'apiKey': event.target.value}); | 150 | this.props.onCredentialsChange(event.target.value, this.props.apiSecret); |
24 | }, | 151 | }, |
25 | handleApiSecretChange: function(event) { | 152 | handleApiSecretChange: function(event) { |
26 | this.setState({'apiSecret': event.target.value}); | 153 | this.props.onCredentialsChange(this.props.apiKey, event.target.value); |
27 | }, | 154 | }, |
28 | hideMessage: function() { | 155 | onEditClick: function() { |
29 | this.setState({'hideMsg': true}); | 156 | this.setState({'editMode': true}); |
30 | }, | ||
31 | displayMessage: function(msg, ok) { | ||
32 | this.setState({'msg': msg, 'msgOk': ok, 'hideMsg': false}); | ||
33 | }, | 157 | }, |
34 | render: function() { | 158 | render: function() { |
35 | var cName = classNames('form-message', {'hidden': this.state.hideMsg, 'message-ok': this.state.msgOk}); | 159 | var submitType = (this.state.editMode === true) ? 'submit' : 'hidden'; |
160 | var buttonDisplay = (this.state.editMode === true) ? 'none' : 'inline'; | ||
161 | var secretDisplayed = (this.state.editMode === true) ? this.props.apiSecret : 'XXXXXXX'; | ||
162 | var keyDisplayed = (this.state.editMode === true) ? this.props.apiKey : 'XXXXXXX'; | ||
163 | |||
36 | return ( | 164 | return ( |
37 | <div className='row justify-content-center api-credentials-form'> | 165 | <div className='row api-credentials-form'> |
38 | <div className='col-lg-offset-4 col-lg-4 col-md-offset-4 col-md-4 col-sm-offset-4 col-sm-4 col-xs-offset-1 col-xs-10'> | 166 | <div className='offset-3 col-6 box'> |
167 | <span className='text-center'>Poloniex credentials</span> | ||
168 | <hr/> | ||
39 | <form role='form' onSubmit={this.handleSubmit}> | 169 | <form role='form' onSubmit={this.handleSubmit}> |
40 | <input className='form-control' type='text' placeholder='apiKey' value={this.state.apiKey} onChange={this.handleApiKeyChange} /> | 170 | <label className='w-100'>Key: |
41 | <input className='form-control' type='text' placeholder='apiSecret' value={this.state.apiSecret} onChange={this.handleApiSecretChange} /> | 171 | <input className='form-control' type='text' placeholder='key' value={keyDisplayed} onChange={this.handleApiKeyChange} disabled={!this.state.editMode}/> |
42 | <input className='form-control submit' type='submit' value='Save' /> | 172 | </label> |
43 | <div className={cName} ref='message'>{this.state.msg}</div> | 173 | <label className='w-100'>Secret: |
174 | <input className='form-control' type='text' placeholder='secret' value={secretDisplayed} onChange={this.handleApiSecretChange} disabled={!this.state.editMode}/> | ||
175 | </label> | ||
176 | <input className='form-control submit' type={submitType} value='Save' /> | ||
177 | <button className='form-control submit' style={{display: buttonDisplay}} onSubmit={null} onClick={this.onEditClick} type='button'>Show/Edit</button> | ||
44 | </form> | 178 | </form> |
45 | </div> | 179 | </div> |
46 | </div> | 180 | </div> |
47 | ); | 181 | ); |
48 | } | 182 | } |
49 | }); | 183 | }); |
184 | |||
185 | module.exports.PoloniexCredentialsForm = PoloniexCredentialsForm; | ||
diff --git a/cmd/web/js/signin.jsx b/cmd/web/js/signin.jsx index 443a461..a2cfd1b 100644 --- a/cmd/web/js/signin.jsx +++ b/cmd/web/js/signin.jsx | |||
@@ -35,8 +35,8 @@ module.exports.SigninForm = React.createClass({ | |||
35 | render: function() { | 35 | render: function() { |
36 | var cName = classNames('form-message', {'hidden': this.state.hideMsg, 'message-ok': this.state.msgOk}); | 36 | var cName = classNames('form-message', {'hidden': this.state.hideMsg, 'message-ok': this.state.msgOk}); |
37 | return ( | 37 | return ( |
38 | <div className='row justify-content-center sign-in'> | 38 | <div className='row sign-in'> |
39 | <div className='col-lg-offset-4 col-lg-4 col-md-offset-4 col-md-4 col-sm-offset-4 col-sm-4 col-xs-offset-1 col-xs-10'> | 39 | <div className='offset-4 col-4 col-xs-offset-1 col-xs-10 text-center'> |
40 | <form role='form' onSubmit={this.handleSubmit}> | 40 | <form role='form' onSubmit={this.handleSubmit}> |
41 | <input className='form-control' type='email' placeholder='email' onChange={this.handleEmailChange} /> | 41 | <input className='form-control' type='email' placeholder='email' onChange={this.handleEmailChange} /> |
42 | <input className='form-control' type='password' placeholder='password' onChange={this.handlePasswordChange} /> | 42 | <input className='form-control' type='password' placeholder='password' onChange={this.handlePasswordChange} /> |
diff --git a/cmd/web/js/signup.jsx b/cmd/web/js/signup.jsx index 149125a..404a828 100644 --- a/cmd/web/js/signup.jsx +++ b/cmd/web/js/signup.jsx | |||
@@ -40,8 +40,8 @@ module.exports.SignupForm = React.createClass({ | |||
40 | render: function() { | 40 | render: function() { |
41 | var cName = classNames('form-message', {'hidden': this.state.hideMsg, 'message-ok': this.state.msgOk}); | 41 | var cName = classNames('form-message', {'hidden': this.state.hideMsg, 'message-ok': this.state.msgOk}); |
42 | return ( | 42 | return ( |
43 | <div className='row justify-content-center sign-in'> | 43 | <div className='row sign-in'> |
44 | <div className='col-lg-offset-4 col-lg-4 col-md-offset-4 col-md-4 col-sm-offset-4 col-sm-4 col-xs-offset-1 col-xs-10'> | 44 | <div className='offset-4 col-4 col-xs-offset-1 col-xs-10 text-center'> |
45 | <form role='form' onSubmit={this.handleSubmit}> | 45 | <form role='form' onSubmit={this.handleSubmit}> |
46 | <input className='form-control' type='email' placeholder='email' onChange={this.handleEmailChange} /> | 46 | <input className='form-control' type='email' placeholder='email' onChange={this.handleEmailChange} /> |
47 | <input className='form-control' type='password' placeholder='password' onChange={this.handlePasswordChange} /> | 47 | <input className='form-control' type='password' placeholder='password' onChange={this.handlePasswordChange} /> |