]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front.git/blob - cmd/web/js/account.jsx
Account information panel.
[perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Front.git] / cmd / web / js / account.jsx
1 import Api from './api.js';
2 import React from 'react';
3 import classnames from 'classnames';
4
5 class Panel extends React.Component {
6 render = () => {
7 if (this.props.component === null) {
8 return <div></div>;
9 }
10
11 var className = classnames('row', this.props.topClassName);
12
13 return (
14 <div className={className}>
15 <div className="box col-12">
16 <div className="row">
17 <div className="col-4">{this.props.title}</div>
18 </div>
19 <hr/>
20 {this.props.component}
21 </div>
22 </div>);
23 }
24 }
25
26 class AccountInformation extends React.Component {
27 constructor(props) {
28 super(props);
29 this.state = {'email': null};
30 }
31
32 loadAccount = () => {
33 Api.Call('USER_ACCOUNT', {}, function(err, status, data) {
34 if (err) {
35 console.error(err, data);
36 return;
37 }
38
39 this.setState({'email': data.email});
40 }.bind(this));
41 }
42
43 componentDidMount = () => {
44 this.loadAccount();
45 }
46
47 render = () => {
48 var component = <p>Loading...</p>;
49 if (this.state.email !== null) {
50 component = <p>Email: {this.state.email}</p>;
51 }
52
53 return component;
54 }
55
56 }
57
58 class PoloniexConfiguration extends React.Component {
59 constructor(props) {
60 super(props);
61 this.state = {'apiKey': '', 'apiSecret': '', 'status': 'loading', 'editMode': false};
62 }
63
64 checkCredentials = () => {
65 Api.Call('MARKET_TEST_CREDENTIALS', {'name': 'poloniex'}, function(err, status, data) {
66 if (err) {
67 console.error(err, data);
68 if (err.code === 'invalid_market_credentials') {
69 this.setState({'status': 'invalidCredentials'});
70 } else if (err.code === 'ip_restricted_api_key') {
71 this.setState({'status': 'ipRestricted'});
72 } else if (err.code === 'market_credentials_not_configured') {
73 this.setState({'status': 'emptyCredentials'});
74 }
75 return;
76 }
77
78 this.setState({'status': 'ok'});
79 }.bind(this));
80 }
81
82 handleCredentialsChange = (key, secret) => {
83 this.setState({'apiKey': key, 'apiSecret': secret});
84 }
85
86 handleCredentialsSubmit = () => {
87 this.setState({'status': 'loading', 'editMode': false});
88 Api.Call('UPDATE_MARKET', {'key': this.state.apiKey, 'secret': this.state.apiSecret, 'name': 'poloniex'}, function(err, status, data) {
89 if (err) {
90 console.error(err, data);
91 if (err.code === 'invalid_market_credentials') {
92 this.setState({'status': 'invalidCredentials'});
93 } else if (err.code === 'ip_restricted_api_key') {
94 this.setState({'status': 'ipRestricted'});
95 }
96 return;
97 }
98
99 this.checkCredentials();
100 }.bind(this));
101 }
102
103 componentDidMount = () => {
104 this.checkCredentials();
105 }
106
107 onEditClick = () => {
108 Api.Call('MARKET', {'name': 'poloniex'}, function(err, status, data) {
109 this.setState({'editMode': true});
110 if (err) {
111 console.error(err, data);
112 return;
113 }
114
115 var newStatus = this.state.status;
116 if (!data.key || !data.secret) {
117 newStatus = 'emptyCredentials';
118 }
119
120 this.setState({'apiKey': data.key, 'apiSecret': data.secret, 'status': newStatus});
121 }.bind(this));
122 }
123
124 render = () => {
125 var displayText = null;
126 switch (this.state.status) {
127 case 'loading':
128 displayText = 'Checking Poloniex credentials...';
129 break;
130 case 'invalidCredentials':
131 displayText = 'Invalid poloniex credentials';
132 break;
133 case 'ipRestricted':
134 displayText = 'Your API key is IP restricted.';
135 break;
136 case 'emptyCredentials':
137 displayText = 'Please provide poloniex credentials';
138 break;
139 case 'ok':
140 displayText = 'You are all set !';
141 break;
142 default:
143 console.error('unknown status', this.state.status);
144 displayText = null;
145 }
146
147 return (
148 <PoloniexCredentialsForm onLoadCredentials={this.onLoadCredentials}
149 onCredentialsSubmit={this.handleCredentialsSubmit}
150 onCredentialsChange={this.handleCredentialsChange}
151 apiSecret={this.state.apiSecret}
152 apiKey={this.state.apiKey}
153 status={this.state.status}
154 statusMessage={displayText}
155 editMode={this.state.editMode}
156 onEditClick={this.onEditClick}/>
157 );
158 }
159 }
160
161 class PoloniexCredentialsForm extends React.Component {
162 handleSubmit = (e) => {
163 this.props.onCredentialsSubmit();
164 e.preventDefault();
165 }
166
167 handleApiKeyChange = (event) => {
168 this.props.onCredentialsChange(event.target.value, this.props.apiSecret);
169 }
170
171 handleApiSecretChange = (event) => {
172 this.props.onCredentialsChange(this.props.apiKey, event.target.value);
173 }
174
175 render = () => {
176 var submitType = this.props.editMode === true ? 'submit' : 'hidden';
177 var buttonDisplay = this.props.editMode === true ? 'none' : 'inline';
178 var secretDisplayed = this.props.editMode === true ? this.props.apiSecret : 'XXXXXXX';
179 var keyDisplayed = this.props.editMode === true ? this.props.apiKey : 'XXXXXXX';
180
181 var iconName = 'icon-cancel-circled';
182 switch (this.props.status) {
183 case 'loading':
184 iconName = 'icon-hourglass-2';
185 break;
186 case 'ok':
187 iconName = 'icon-ok-circled';
188 break;
189 }
190
191 return (
192 <React.Fragment>
193 <div className="row config-status">
194 <div className="col-12">
195 <span><i className={iconName}></i>{this.props.statusMessage}</span>
196 </div>
197 </div>
198 <div className="row">
199 <div className="col-12">
200 <form role="form" onSubmit={this.handleSubmit}>
201 <label className="w-100">Key:
202 <input className="form-control" type="text" placeholder="key" value={keyDisplayed} onChange={this.handleApiKeyChange} disabled={!this.props.editMode}/>
203 </label>
204 <label className="w-100">Secret:
205 <input className="form-control" type="text" placeholder="secret" value={secretDisplayed} onChange={this.handleApiSecretChange} disabled={!this.props.editMode}/>
206 </label>
207 <input className="form-control submit" type={submitType} value="Save" />
208 <button className="form-control submit" style={{display: buttonDisplay}} onSubmit={null} onClick={this.props.onEditClick} type="button">Show/Edit</button>
209 </form>
210 </div>
211 </div>
212 </React.Fragment>
213 );
214 }
215 }
216
217 class UserAccount extends React.Component {
218 render = () => {
219 return (
220 <React.Fragment>
221 <Panel component={<AccountInformation/>} title="Account" />
222 <Panel component={<PoloniexConfiguration/>} title="Poloniex credentials" topClassName="api-credentials-form" />
223 </React.Fragment>
224 );
225 }
226 }
227
228 export default UserAccount;