aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorjloup <jeanloup.jamet@gmail.com>2018-02-22 11:31:59 +0100
committerjloup <jeanloup.jamet@gmail.com>2018-02-22 11:31:59 +0100
commit2f91f20a8645339385ada602684f4957f20f4da4 (patch)
treea084cf293af15cc6ea6a1417edad51fcf0674947 /cmd
parent3602fbf8412d69900d793a963c8e774f487f5e45 (diff)
downloadFront-2f91f20a8645339385ada602684f4957f20f4da4.tar.gz
Front-2f91f20a8645339385ada602684f4957f20f4da4.tar.zst
Front-2f91f20a8645339385ada602684f4957f20f4da4.zip
Poloniex connection.
Diffstat (limited to 'cmd')
-rw-r--r--cmd/web/Makefile19
-rw-r--r--cmd/web/js/api.js11
-rw-r--r--cmd/web/js/main.jsx41
-rw-r--r--cmd/web/js/otp.jsx6
-rw-r--r--cmd/web/js/poloniex.jsx176
-rw-r--r--cmd/web/js/signin.jsx4
-rw-r--r--cmd/web/js/signup.jsx4
-rw-r--r--cmd/web/static/cryptocoins.css1150
-rw-r--r--cmd/web/static/cryptocoins.ttfbin0 -> 96448 bytes
-rw-r--r--cmd/web/static/cryptocoins.woffbin0 -> 58768 bytes
-rw-r--r--cmd/web/static/cryptocoins.woff2bin0 -> 49976 bytes
-rw-r--r--cmd/web/static/index.html1
-rw-r--r--cmd/web/static/style.css15
13 files changed, 1361 insertions, 66 deletions
diff --git a/cmd/web/Makefile b/cmd/web/Makefile
index 1d98085..2ebb734 100644
--- a/cmd/web/Makefile
+++ b/cmd/web/Makefile
@@ -6,6 +6,7 @@ SRC_DIR=js
6BUILD_DIR=build/js 6BUILD_DIR=build/js
7JSX_SRC= main.jsx signup.jsx signin.jsx otp.jsx poloniex.jsx 7JSX_SRC= main.jsx signup.jsx signin.jsx otp.jsx poloniex.jsx
8JS_SRC= cookies.js app.js api.js 8JS_SRC= cookies.js app.js api.js
9STATIC_FILES= index.html style.css cryptocoins.css cryptocoins.ttf cryptocoins.woff cryptocoins.woff2
9JSX_OBJS=$(addprefix $(BUILD_DIR)/,$(JSX_SRC:.jsx=.js)) 10JSX_OBJS=$(addprefix $(BUILD_DIR)/,$(JSX_SRC:.jsx=.js))
10JS_OBJS=$(addprefix $(BUILD_DIR)/,$(JS_SRC)) 11JS_OBJS=$(addprefix $(BUILD_DIR)/,$(JS_SRC))
11STATIC_BUILD_DIR=build/static 12STATIC_BUILD_DIR=build/static
@@ -16,18 +17,18 @@ install:
16 yarn --version 17 yarn --version
17 yarn install 18 yarn install
18 19
19static: js $(STATIC_BUILD_DIR)/index.html $(STATIC_BUILD_DIR)/style.css 20static: $(STATIC_BUILD_DIR) js $(addprefix $(STATIC_BUILD_DIR)/, $(STATIC_FILES))
20 21
21js: build/static/main.js 22js: build/static/main.js
22 23
23$(STATIC_BUILD_DIR)/index.html: static/index.html 24$(STATIC_BUILD_DIR)/%: static/%
24 cp static/index.html $@ 25 cp $< $@
25 26
26$(STATIC_BUILD_DIR)/style.css: static/style.css 27$(STATIC_BUILD_DIR):
27 cp static/style.css $@ 28 mkdir -p $(BUILD_DIR)
29 mkdir -p $@
28 30
29$(BUILD_DIR)/%.js: $(SRC_DIR)/%.jsx 31$(BUILD_DIR)/%.js: $(SRC_DIR)/%.jsx
30 mkdir -p $(@D)
31 jscs --fix $< 32 jscs --fix $<
32 babel $< -o $@ 33 babel $< -o $@
33 jshint $@ 34 jshint $@
@@ -42,11 +43,11 @@ build/static/main.js: $(JSX_OBJS) $(JS_OBJS) env/$(ENV).env
42 -t [ debowerify ] \ 43 -t [ debowerify ] \
43 $(BUILD_DIR)/main.js -o $@ 44 $(BUILD_DIR)/main.js -o $@
44 45
45build/webapp.tar.gz: $(STATIC_BUILD_DIR)/main.js $(STATIC_BUILD_DIR)/index.html $(STATIC_BUILD_DIR)/style.css 46build/webapp.tar.gz: $(addprefix $(STATIC_BUILD_DIR)/, $(STATIC_FILES)) build/static/main.js
46 tar czf $@ --directory=$(dir $<) $(notdir $^) 47 tar czf $@ --directory=$(dir $<) $(notdir $^)
47 48
48release: build/webapp.tar.gz 49release: $(STATIC_BUILD_DIR) build/webapp.tar.gz
49 50
50clean: 51clean:
51 rm -rf build 52 rm -rf build
52 rm -rf node_modules \ No newline at end of file 53 rm -rf node_modules
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 @@
1var SignupForm = require('./signup.js').SignupForm; 1var SignupForm = require('./signup.js').SignupForm;
2var SigninForm = require('./signin.js').SigninForm; 2var SigninForm = require('./signin.js').SigninForm;
3var OtpEnrollForm = require('./otp.js').OtpEnrollForm; 3var OtpEnrollForm = require('./otp.js').OtpEnrollForm;
4var PoloniexForm = require('./poloniex.js').PoloniexForm; 4var PoloniexController = require('./poloniex.js').PoloniexController;
5var App = require('./app.js'); 5var App = require('./app.js');
6var Api = require('./api.js').Api; 6var Api = require('./api.js').Api;
7var cookies = require('./cookies.js'); 7var cookies = require('./cookies.js');
8 8
9var Logo = React.createClass({ 9var 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
51App.page('/me', true, function(context) { 53App.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
69App.page('/otp/setup', true, function(context) { 62App.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 @@
1var Api = require('./api.js').Api; 1var Api = require('./api.js').Api;
2var App = require('./app.js');
3var classNames = require('classnames'); 2var classNames = require('classnames');
4 3
5module.exports.PoloniexForm = React.createClass({ 4module.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
86var 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
138module.exports.PoloniexBalance = PoloniexBalance;
139
140var 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
185module.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} />
diff --git a/cmd/web/static/cryptocoins.css b/cmd/web/static/cryptocoins.css
new file mode 100644
index 0000000..6829169
--- /dev/null
+++ b/cmd/web/static/cryptocoins.css
@@ -0,0 +1,1150 @@
1/*! Cryptocoins - cryptocurrency icon font | https://github.com/allienworks/cryptocoins */
2
3@font-face {
4 font-family: "cryptocoins";
5 src: url('cryptocoins.woff2') format('woff2'),
6 url('cryptocoins.woff') format('woff'),
7 url('cryptocoins.ttf') format('truetype');
8}
9
10/* .cc:before { */
11.cc::before {
12 font-family: "cryptocoins";
13 -webkit-font-smoothing: antialiased;
14 -moz-osx-font-smoothing: grayscale;
15 font-style: normal;
16 font-variant: normal;
17 font-weight: normal;
18 /* speak: none; only necessary if not using the private unicode range (firstGlyph option) */
19 text-decoration: none;
20 text-transform: none;
21}
22
23
24.cc.ADA-alt::before {
25 content: "\E001";
26}
27
28.cc.ADA::before {
29 content: "\E002";
30}
31
32.cc.ADC-alt::before {
33 content: "\E003";
34}
35
36.cc.ADC::before {
37 content: "\E004";
38}
39
40.cc.AEON-alt::before {
41 content: "\E005";
42}
43
44.cc.AEON::before {
45 content: "\E006";
46}
47
48.cc.AMP-alt::before {
49 content: "\E007";
50}
51
52.cc.AMP::before {
53 content: "\E008";
54}
55
56.cc.ANC-alt::before {
57 content: "\E009";
58}
59
60.cc.ANC::before {
61 content: "\E00A";
62}
63
64.cc.ARCH-alt::before {
65 content: "\E00B";
66}
67
68.cc.ARCH::before {
69 content: "\E00C";
70}
71
72.cc.ARDR-alt::before {
73 content: "\E00D";
74}
75
76.cc.ARDR::before {
77 content: "\E00E";
78}
79
80.cc.ARK-alt::before {
81 content: "\E00F";
82}
83
84.cc.ARK::before {
85 content: "\E010";
86}
87
88.cc.AUR-alt::before {
89 content: "\E011";
90}
91
92.cc.AUR::before {
93 content: "\E012";
94}
95
96.cc.BANX-alt::before {
97 content: "\E013";
98}
99
100.cc.BANX::before {
101 content: "\E014";
102}
103
104.cc.BAT-alt::before {
105 content: "\E015";
106}
107
108.cc.BAT::before {
109 content: "\E016";
110}
111
112.cc.BAY-alt::before {
113 content: "\E017";
114}
115
116.cc.BAY::before {
117 content: "\E018";
118}
119
120.cc.BC-alt::before {
121 content: "\E019";
122}
123
124.cc.BC::before {
125 content: "\E01A";
126}
127
128.cc.BCH-alt::before {
129 content: "\E01B";
130}
131
132.cc.BCH::before {
133 content: "\E01C";
134}
135
136.cc.BCN-alt::before {
137 content: "\E01D";
138}
139
140.cc.BCN::before {
141 content: "\E01E";
142}
143
144.cc.BFT-alt::before {
145 content: "\E01F";
146}
147
148.cc.BFT::before {
149 content: "\E020";
150}
151
152.cc.BRK-alt::before {
153 content: "\E021";
154}
155
156.cc.BRK::before {
157 content: "\E022";
158}
159
160.cc.BRX-alt::before {
161 content: "\E023";
162}
163
164.cc.BRX::before {
165 content: "\E024";
166}
167
168.cc.BSD-alt::before {
169 content: "\E025";
170}
171
172.cc.BSD::before {
173 content: "\E026";
174}
175
176.cc.BTA::before {
177 content: "\E027";
178}
179
180.cc.BTC-alt::before {
181 content: "\E028";
182}
183
184.cc.BTC::before {
185 content: "\E029";
186}
187
188.cc.BTCD-alt::before {
189 content: "\E02A";
190}
191
192.cc.BTCD::before {
193 content: "\E02B";
194}
195
196.cc.BTM-alt::before {
197 content: "\E02C";
198}
199
200.cc.BTM::before {
201 content: "\E02D";
202}
203
204.cc.BTS-alt::before {
205 content: "\E02E";
206}
207
208.cc.BTS::before {
209 content: "\E02F";
210}
211
212.cc.CLAM-alt::before {
213 content: "\E030";
214}
215
216.cc.CLAM::before {
217 content: "\E031";
218}
219
220.cc.CLOAK-alt::before {
221 content: "\E032";
222}
223
224.cc.CLOAK::before {
225 content: "\E033";
226}
227
228.cc.DAO-alt::before {
229 content: "\E034";
230}
231
232.cc.DAO::before {
233 content: "\E035";
234}
235
236.cc.DASH-alt::before {
237 content: "\E036";
238}
239
240.cc.DASH::before {
241 content: "\E037";
242}
243
244.cc.DCR-alt::before {
245 content: "\E038";
246}
247
248.cc.DCR::before {
249 content: "\E039";
250}
251
252.cc.DCT-alt::before {
253 content: "\E03A";
254}
255
256.cc.DCT::before {
257 content: "\E03B";
258}
259
260.cc.DGB-alt::before {
261 content: "\E03C";
262}
263
264.cc.DGB::before {
265 content: "\E03D";
266}
267
268.cc.DGD::before {
269 content: "\E03E";
270}
271
272.cc.DGX::before {
273 content: "\E03F";
274}
275
276.cc.DMD-alt::before {
277 content: "\E040";
278}
279
280.cc.DMD::before {
281 content: "\E041";
282}
283
284.cc.DOGE-alt::before {
285 content: "\E042";
286}
287
288.cc.DOGE::before {
289 content: "\E043";
290}
291
292.cc.EMC-alt::before {
293 content: "\E044";
294}
295
296.cc.EMC::before {
297 content: "\E045";
298}
299
300.cc.EOS-alt::before {
301 content: "\E046";
302}
303
304.cc.EOS::before {
305 content: "\E047";
306}
307
308.cc.ERC-alt::before {
309 content: "\E048";
310}
311
312.cc.ERC::before {
313 content: "\E049";
314}
315
316.cc.ETC-alt::before {
317 content: "\E04A";
318}
319
320.cc.ETC::before {
321 content: "\E04B";
322}
323
324.cc.ETH-alt::before {
325 content: "\E04C";
326}
327
328.cc.ETH::before {
329 content: "\E04D";
330}
331
332.cc.FC2-alt::before {
333 content: "\E04E";
334}
335
336.cc.FC2::before {
337 content: "\E04F";
338}
339
340.cc.FCT-alt::before {
341 content: "\E050";
342}
343
344.cc.FCT::before {
345 content: "\E051";
346}
347
348.cc.FLO-alt::before {
349 content: "\E052";
350}
351
352.cc.FLO::before {
353 content: "\E053";
354}
355
356.cc.FRK-alt::before {
357 content: "\E054";
358}
359
360.cc.FRK::before {
361 content: "\E055";
362}
363
364.cc.FTC-alt::before {
365 content: "\E056";
366}
367
368.cc.FTC::before {
369 content: "\E057";
370}
371
372.cc.GAME-alt::before {
373 content: "\E058";
374}
375
376.cc.GAME::before {
377 content: "\E059";
378}
379
380.cc.GBYTE-alt::before {
381 content: "\E05A";
382}
383
384.cc.GBYTE::before {
385 content: "\E05B";
386}
387
388.cc.GDC-alt::before {
389 content: "\E05C";
390}
391
392.cc.GDC::before {
393 content: "\E05D";
394}
395
396.cc.GEMZ-alt::before {
397 content: "\E05E";
398}
399
400.cc.GEMZ::before {
401 content: "\E05F";
402}
403
404.cc.GLD-alt::before {
405 content: "\E060";
406}
407
408.cc.GLD::before {
409 content: "\E061";
410}
411
412.cc.GNO-alt::before {
413 content: "\E062";
414}
415
416.cc.GNO::before {
417 content: "\E063";
418}
419
420.cc.GNT-alt::before {
421 content: "\E064";
422}
423
424.cc.GNT::before {
425 content: "\E065";
426}
427
428.cc.GOLOS-alt::before {
429 content: "\E066";
430}
431
432.cc.GOLOS::before {
433 content: "\E067";
434}
435
436.cc.GRC-alt::before {
437 content: "\E068";
438}
439
440.cc.GRC::before {
441 content: "\E069";
442}
443
444.cc.GRS::before {
445 content: "\E06A";
446}
447
448.cc.HEAT-alt::before {
449 content: "\E06B";
450}
451
452.cc.HEAT::before {
453 content: "\E06C";
454}
455
456.cc.ICN-alt::before {
457 content: "\E06D";
458}
459
460.cc.ICN::before {
461 content: "\E06E";
462}
463
464.cc.IFC-alt::before {
465 content: "\E06F";
466}
467
468.cc.IFC::before {
469 content: "\E070";
470}
471
472.cc.INCNT-alt::before {
473 content: "\E071";
474}
475
476.cc.INCNT::before {
477 content: "\E072";
478}
479
480.cc.IOC-alt::before {
481 content: "\E073";
482}
483
484.cc.IOC::before {
485 content: "\E074";
486}
487
488.cc.IOTA-alt::before {
489 content: "\E075";
490}
491
492.cc.IOTA::before {
493 content: "\E076";
494}
495
496.cc.JBS-alt::before {
497 content: "\E077";
498}
499
500.cc.JBS::before {
501 content: "\E078";
502}
503
504.cc.KMD-alt::before {
505 content: "\E079";
506}
507
508.cc.KMD::before {
509 content: "\E07A";
510}
511
512.cc.KOBO::before {
513 content: "\E07B";
514}
515
516.cc.KORE-alt::before {
517 content: "\E07C";
518}
519
520.cc.KORE::before {
521 content: "\E07D";
522}
523
524.cc.LBC-alt::before {
525 content: "\E07E";
526}
527
528.cc.LBC::before {
529 content: "\E07F";
530}
531
532.cc.LDOGE-alt::before {
533 content: "\E080";
534}
535
536.cc.LDOGE::before {
537 content: "\E081";
538}
539
540.cc.LSK-alt::before {
541 content: "\E082";
542}
543
544.cc.LSK::before {
545 content: "\E083";
546}
547
548.cc.LTC-alt::before {
549 content: "\E084";
550}
551
552.cc.LTC::before {
553 content: "\E085";
554}
555
556.cc.MAID-alt::before {
557 content: "\E086";
558}
559
560.cc.MAID::before {
561 content: "\E087";
562}
563
564.cc.MCO-alt::before {
565 content: "\E088";
566}
567
568.cc.MCO::before {
569 content: "\E089";
570}
571
572.cc.MINT-alt::before {
573 content: "\E08A";
574}
575
576.cc.MINT::before {
577 content: "\E08B";
578}
579
580.cc.MONA-alt::before {
581 content: "\E08C";
582}
583
584.cc.MONA::before {
585 content: "\E08D";
586}
587
588.cc.MRC::before {
589 content: "\E08E";
590}
591
592.cc.MSC-alt::before {
593 content: "\E08F";
594}
595
596.cc.MSC::before {
597 content: "\E090";
598}
599
600.cc.MTR-alt::before {
601 content: "\E091";
602}
603
604.cc.MTR::before {
605 content: "\E092";
606}
607
608.cc.MUE-alt::before {
609 content: "\E093";
610}
611
612.cc.MUE::before {
613 content: "\E094";
614}
615
616.cc.NBT::before {
617 content: "\E095";
618}
619
620.cc.NEO-alt::before {
621 content: "\E096";
622}
623
624.cc.NEO::before {
625 content: "\E097";
626}
627
628.cc.NEOS-alt::before {
629 content: "\E098";
630}
631
632.cc.NEOS::before {
633 content: "\E099";
634}
635
636.cc.NEU-alt::before {
637 content: "\E09A";
638}
639
640.cc.NEU::before {
641 content: "\E09B";
642}
643
644.cc.NLG-alt::before {
645 content: "\E09C";
646}
647
648.cc.NLG::before {
649 content: "\E09D";
650}
651
652.cc.NMC-alt::before {
653 content: "\E09E";
654}
655
656.cc.NMC::before {
657 content: "\E09F";
658}
659
660.cc.NOTE-alt::before {
661 content: "\E0A0";
662}
663
664.cc.NOTE::before {
665 content: "\E0A1";
666}
667
668.cc.NVC-alt::before {
669 content: "\E0A2";
670}
671
672.cc.NVC::before {
673 content: "\E0A3";
674}
675
676.cc.NXT-alt::before {
677 content: "\E0A4";
678}
679
680.cc.NXT::before {
681 content: "\E0A5";
682}
683
684.cc.OK-alt::before {
685 content: "\E0A6";
686}
687
688.cc.OK::before {
689 content: "\E0A7";
690}
691
692.cc.OMG-alt::before {
693 content: "\E0A8";
694}
695
696.cc.OMG::before {
697 content: "\E0A9";
698}
699
700.cc.OMNI-alt::before {
701 content: "\E0AA";
702}
703
704.cc.OMNI::before {
705 content: "\E0AB";
706}
707
708.cc.OPAL-alt::before {
709 content: "\E0AC";
710}
711
712.cc.OPAL::before {
713 content: "\E0AD";
714}
715
716.cc.PART-alt::before {
717 content: "\E0AE";
718}
719
720.cc.PART::before {
721 content: "\E0AF";
722}
723
724.cc.PIGGY-alt::before {
725 content: "\E0B0";
726}
727
728.cc.PIGGY::before {
729 content: "\E0B1";
730}
731
732.cc.PINK-alt::before {
733 content: "\E0B2";
734}
735
736.cc.PINK::before {
737 content: "\E0B3";
738}
739
740.cc.PIVX-alt::before {
741 content: "\E0B4";
742}
743
744.cc.PIVX::before {
745 content: "\E0B5";
746}
747
748.cc.POT-alt::before {
749 content: "\E0B6";
750}
751
752.cc.POT::before {
753 content: "\E0B7";
754}
755
756.cc.PPC-alt::before {
757 content: "\E0B8";
758}
759
760.cc.PPC::before {
761 content: "\E0B9";
762}
763
764.cc.QRK-alt::before {
765 content: "\E0BA";
766}
767
768.cc.QRK::before {
769 content: "\E0BB";
770}
771
772.cc.QTUM-alt::before {
773 content: "\E0BC";
774}
775
776.cc.QTUM::before {
777 content: "\E0BD";
778}
779
780.cc.RADS-alt::before {
781 content: "\E0BE";
782}
783
784.cc.RADS::before {
785 content: "\E0BF";
786}
787
788.cc.RBIES-alt::before {
789 content: "\E0C0";
790}
791
792.cc.RBIES::before {
793 content: "\E0C1";
794}
795
796.cc.RBT-alt::before {
797 content: "\E0C2";
798}
799
800.cc.RBT::before {
801 content: "\E0C3";
802}
803
804.cc.RBY-alt::before {
805 content: "\E0C4";
806}
807
808.cc.RBY::before {
809 content: "\E0C5";
810}
811
812.cc.RDD-alt::before {
813 content: "\E0C6";
814}
815
816.cc.RDD::before {
817 content: "\E0C7";
818}
819
820.cc.REP-alt::before {
821 content: "\E0C8";
822}
823
824.cc.REP::before {
825 content: "\E0C9";
826}
827
828.cc.RISE-alt::before {
829 content: "\E0CA";
830}
831
832.cc.RISE::before {
833 content: "\E0CB";
834}
835
836.cc.SALT-alt::before {
837 content: "\E0CC";
838}
839
840.cc.SALT::before {
841 content: "\E0CD";
842}
843
844.cc.SAR-alt::before {
845 content: "\E0CE";
846}
847
848.cc.SAR::before {
849 content: "\E0CF";
850}
851
852.cc.SCOT-alt::before {
853 content: "\E0D0";
854}
855
856.cc.SCOT::before {
857 content: "\E0D1";
858}
859
860.cc.SDC-alt::before {
861 content: "\E0D2";
862}
863
864.cc.SDC::before {
865 content: "\E0D3";
866}
867
868.cc.SIA-alt::before {
869 content: "\E0D4";
870}
871
872.cc.SIA::before {
873 content: "\E0D5";
874}
875
876.cc.SJCX-alt::before {
877 content: "\E0D6";
878}
879
880.cc.SJCX::before {
881 content: "\E0D7";
882}
883
884.cc.SLG-alt::before {
885 content: "\E0D8";
886}
887
888.cc.SLG::before {
889 content: "\E0D9";
890}
891
892.cc.SLS-alt::before {
893 content: "\E0DA";
894}
895
896.cc.SLS::before {
897 content: "\E0DB";
898}
899
900.cc.SNRG-alt::before {
901 content: "\E0DC";
902}
903
904.cc.SNRG::before {
905 content: "\E0DD";
906}
907
908.cc.START-alt::before {
909 content: "\E0DE";
910}
911
912.cc.START::before {
913 content: "\E0DF";
914}
915
916.cc.STEEM-alt::before {
917 content: "\E0E0";
918}
919
920.cc.STEEM::before {
921 content: "\E0E1";
922}
923
924.cc.STR-alt::before {
925 content: "\E0E2";
926}
927
928.cc.STR::before {
929 content: "\E0E3";
930}
931
932.cc.STRAT-alt::before {
933 content: "\E0E4";
934}
935
936.cc.STRAT::before {
937 content: "\E0E5";
938}
939
940.cc.SWIFT-alt::before {
941 content: "\E0E6";
942}
943
944.cc.SWIFT::before {
945 content: "\E0E7";
946}
947
948.cc.SYNC-alt::before {
949 content: "\E0E8";
950}
951
952.cc.SYNC::before {
953 content: "\E0E9";
954}
955
956.cc.SYS-alt::before {
957 content: "\E0EA";
958}
959
960.cc.SYS::before {
961 content: "\E0EB";
962}
963
964.cc.TRIG-alt::before {
965 content: "\E0EC";
966}
967
968.cc.TRIG::before {
969 content: "\E0ED";
970}
971
972.cc.TX-alt::before {
973 content: "\E0EE";
974}
975
976.cc.TX::before {
977 content: "\E0EF";
978}
979
980.cc.UBQ-alt::before {
981 content: "\E0F0";
982}
983
984.cc.UBQ::before {
985 content: "\E0F1";
986}
987
988.cc.UNITY-alt::before {
989 content: "\E0F2";
990}
991
992.cc.UNITY::before {
993 content: "\E0F3";
994}
995
996.cc.USDT-alt::before {
997 content: "\E0F4";
998}
999
1000.cc.USDT::before {
1001 content: "\E0F5";
1002}
1003
1004.cc.VIOR-alt::before {
1005 content: "\E0F6";
1006}
1007
1008.cc.VIOR::before {
1009 content: "\E0F7";
1010}
1011
1012.cc.VNL-alt::before {
1013 content: "\E0F8";
1014}
1015
1016.cc.VNL::before {
1017 content: "\E0F9";
1018}
1019
1020.cc.VPN-alt::before {
1021 content: "\E0FA";
1022}
1023
1024.cc.VPN::before {
1025 content: "\E0FB";
1026}
1027
1028.cc.VRC-alt::before {
1029 content: "\E0FC";
1030}
1031
1032.cc.VRC::before {
1033 content: "\E0FD";
1034}
1035
1036.cc.VTC-alt::before {
1037 content: "\E0FE";
1038}
1039
1040.cc.VTC::before {
1041 content: "\E0FF";
1042}
1043
1044.cc.WAVES-alt::before {
1045 content: "\E100";
1046}
1047
1048.cc.WAVES::before {
1049 content: "\E101";
1050}
1051
1052.cc.XAI-alt::before {
1053 content: "\E102";
1054}
1055
1056.cc.XAI::before {
1057 content: "\E103";
1058}
1059
1060.cc.XBS-alt::before {
1061 content: "\E104";
1062}
1063
1064.cc.XBS::before {
1065 content: "\E105";
1066}
1067
1068.cc.XCP-alt::before {
1069 content: "\E106";
1070}
1071
1072.cc.XCP::before {
1073 content: "\E107";
1074}
1075
1076.cc.XEM-alt::before {
1077 content: "\E108";
1078}
1079
1080.cc.XEM::before {
1081 content: "\E109";
1082}
1083
1084.cc.XMR::before {
1085 content: "\E10A";
1086}
1087
1088.cc.XPM-alt::before {
1089 content: "\E10B";
1090}
1091
1092.cc.XPM::before {
1093 content: "\E10C";
1094}
1095
1096.cc.XRP-alt::before {
1097 content: "\E10D";
1098}
1099
1100.cc.XRP::before {
1101 content: "\E10E";
1102}
1103
1104.cc.XTZ-alt::before {
1105 content: "\E10F";
1106}
1107
1108.cc.XTZ::before {
1109 content: "\E110";
1110}
1111
1112.cc.XVG-alt::before {
1113 content: "\E111";
1114}
1115
1116.cc.XVG::before {
1117 content: "\E112";
1118}
1119
1120.cc.XZC-alt::before {
1121 content: "\E113";
1122}
1123
1124.cc.XZC::before {
1125 content: "\E114";
1126}
1127
1128.cc.YBC-alt::before {
1129 content: "\E115";
1130}
1131
1132.cc.YBC::before {
1133 content: "\E116";
1134}
1135
1136.cc.ZEC-alt::before {
1137 content: "\E117";
1138}
1139
1140.cc.ZEC::before {
1141 content: "\E118";
1142}
1143
1144.cc.ZEIT-alt::before {
1145 content: "\E119";
1146}
1147
1148.cc.ZEIT::before {
1149 content: "\E11A";
1150} \ No newline at end of file
diff --git a/cmd/web/static/cryptocoins.ttf b/cmd/web/static/cryptocoins.ttf
new file mode 100644
index 0000000..b92c27d
--- /dev/null
+++ b/cmd/web/static/cryptocoins.ttf
Binary files differ
diff --git a/cmd/web/static/cryptocoins.woff b/cmd/web/static/cryptocoins.woff
new file mode 100644
index 0000000..bf8eb08
--- /dev/null
+++ b/cmd/web/static/cryptocoins.woff
Binary files differ
diff --git a/cmd/web/static/cryptocoins.woff2 b/cmd/web/static/cryptocoins.woff2
new file mode 100644
index 0000000..dcc195c
--- /dev/null
+++ b/cmd/web/static/cryptocoins.woff2
Binary files differ
diff --git a/cmd/web/static/index.html b/cmd/web/static/index.html
index 9a70074..a372517 100644
--- a/cmd/web/static/index.html
+++ b/cmd/web/static/index.html
@@ -11,6 +11,7 @@
11 <title>Cryptoportfolio</title> 11 <title>Cryptoportfolio</title>
12 <link href='https://fonts.googleapis.com/css?family=Fira+Mono' rel='stylesheet' type='text/css'> 12 <link href='https://fonts.googleapis.com/css?family=Fira+Mono' rel='stylesheet' type='text/css'>
13 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous"> 13 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
14 <link rel="stylesheet" type="text/css" href="/public/cryptocoins.css"/>
14 <link rel="stylesheet" type="text/css" href="/public/style.css"/> 15 <link rel="stylesheet" type="text/css" href="/public/style.css"/>
15 <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> 16 <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
16 <!-- WARNING: Respond.js doesn't work if you view the page via file:// --> 17 <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
diff --git a/cmd/web/static/style.css b/cmd/web/static/style.css
index 12af379..bfa43f0 100644
--- a/cmd/web/static/style.css
+++ b/cmd/web/static/style.css
@@ -3,7 +3,6 @@
3body { 3body {
4 font-family: 'Fira Mono', 'Helvetica Neue', Arial, Helvetica, sans-serif; 4 font-family: 'Fira Mono', 'Helvetica Neue', Arial, Helvetica, sans-serif;
5 background-color: rgb(246, 248, 251); 5 background-color: rgb(246, 248, 251);
6 text-align: center;
7} 6}
8 7
9ul { 8ul {
@@ -25,6 +24,10 @@ a:focus {
25 color: inherit; 24 color: inherit;
26} 25}
27 26
27i.cc {
28 font-size: 1.5em;
29}
30
28#logo { 31#logo {
29 text-align: center; 32 text-align: center;
30 display: inline-block; 33 display: inline-block;
@@ -93,8 +96,8 @@ a:focus {
93 background-color: rgb(250, 250, 250); 96 background-color: rgb(250, 250, 250);
94 box-shadow: 0 2px 6px 2px rgba(0,0,0,.05); 97 box-shadow: 0 2px 6px 2px rgba(0,0,0,.05);
95 border-radius: 4px; 98 border-radius: 4px;
96} 99 margin-bottom: 10px;
97 100 margin-top: 10px;
98.box:hover { 101 padding-top: 10px;
99 box-shadow: 0 4px 15px 2px rgba(0,0,0,.20); 102 padding-bottom: 10px;
100} 103} \ No newline at end of file